Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{PrimitiveNumber, PrimitiveNumberRef, PrimitiveUnsigned};
use core::cmp::Ordering;
use core::f32::consts as f32_consts;
use core::f64::consts as f64_consts;
use core::num::FpCategory;
use core::num::{FpCategory, ParseFloatError};

struct SealedToken;

Expand Down Expand Up @@ -70,6 +70,7 @@ pub trait PrimitiveFloat:
+ core::convert::From<i8>
+ core::convert::From<u8>
+ core::ops::Neg<Output = Self>
+ core::str::FromStr<Err = ParseFloatError>
{
/// Approximate number of significant digits in base 10.
const DIGITS: u32;
Expand Down
1 change: 1 addition & 0 deletions src/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ pub trait PrimitiveInteger:
+ core::ops::ShrAssign<u64>
+ core::ops::ShrAssign<u128>
+ core::ops::ShrAssign<usize>
+ core::str::FromStr<Err = ParseIntError>
+ for<'a> core::ops::BitAnd<&'a Self, Output = Self>
+ for<'a> core::ops::BitAndAssign<&'a Self>
+ for<'a> core::ops::BitOr<&'a Self, Output = Self>
Expand Down
9 changes: 8 additions & 1 deletion src/signed.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::convert::Infallible;

use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveUnsigned};

/// Trait for all primitive [signed integer types], including the supertraits [`PrimitiveInteger`]
Expand Down Expand Up @@ -49,7 +51,12 @@ use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveUnsigned};
/// assert_eq!(extended_gcd::<i16>(1071, -462), (21, -3, -7));
/// assert_eq!(extended_gcd::<i64>(6_700_417, 2_147_483_647), (1, 715_828_096, -2_233_473));
/// ```
pub trait PrimitiveSigned: PrimitiveInteger + From<i8> + core::ops::Neg<Output = Self> {
pub trait PrimitiveSigned:
PrimitiveInteger
+ core::convert::From<i8>
+ core::convert::TryFrom<i8, Error = Infallible>
+ core::ops::Neg<Output = Self>
{
/// The unsigned integer type used by methods like [`abs_diff`][Self::abs_diff] and
/// [`checked_add_unsigned`][Self::checked_add_unsigned].
type Unsigned: PrimitiveUnsigned;
Expand Down
55 changes: 54 additions & 1 deletion src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@
extern crate alloc;

use alloc::boxed::Box;
use core::convert::Infallible;
use core::error::Error;
use core::num::{ParseFloatError, ParseIntError};

use crate::{PrimitiveError, PrimitiveInteger, PrimitiveNumber};
use crate::{
PrimitiveError, PrimitiveFloat, PrimitiveInteger, PrimitiveNumber, PrimitiveSigned,
PrimitiveUnsigned,
};

fn check_result<'a, T: PrimitiveNumber, E: PrimitiveError>(r: Result<T, E>, ok: T) {
// Cloning and equating results requires `E: Clone + PartialEq`
Expand All @@ -37,22 +42,70 @@ fn check_result<'a, T: PrimitiveNumber, E: PrimitiveError>(r: Result<T, E>, ok:

#[test]
fn parse() {
// `PrimitiveNumber` is not specific about the `FromStr` error type,
// only constraining that it implements `PrimitiveError`.
fn check<T: PrimitiveNumber>(s: &str, ok: T) {
check_result(s.parse(), ok);
}
check("0", 0u32);
}

#[test]
fn parse_float() {
// `PrimitiveFloat` is specific about the `FromStr` error type.
fn check<T: PrimitiveFloat>(s: &str, ok: T) {
let r: Result<T, ParseFloatError> = s.parse();
assert_eq!(r, Ok(ok));
}
check("0", 0f32);
}

#[test]
fn parse_int() {
// `PrimitiveInteger` is specific about the `FromStr` error type.
fn check<T: PrimitiveInteger>(s: &str, ok: T) {
let r: Result<T, ParseIntError> = s.parse();
assert_eq!(r, Ok(ok));
}
check("0", 0u32);
}

#[test]
fn try_from() {
// `PrimitiveInteger` is not specific about the `TryFrom` error type,
// only constraining that it implements `PrimitiveError`.
fn check<T: PrimitiveInteger>(x: i32, ok: T) {
check_result(T::try_from(x), ok);
}
check(0i32, 0u32);
}

#[test]
fn try_from_signed() {
// `PrimitiveSigned` is specific that `TryFrom<i8>` is infallible.
// (implied by `From<i8>`, but we still need an explicit constraint)
fn check<T: PrimitiveSigned>(x: i8, ok: T) {
let r: Result<T, Infallible> = T::try_from(x);
assert_eq!(r, Ok(ok));
}
check(0i8, 0i32);
}

#[test]
fn try_from_unsigned() {
// `PrimitiveUnsigned` is specific that `TryFrom<u8>` is infallible.
// (implied by `From<u8>`, but we still need an explicit constraint)
fn check<T: PrimitiveUnsigned>(x: u8, ok: T) {
let r: Result<T, Infallible> = T::try_from(x);
assert_eq!(r, Ok(ok));
}
check(0u8, 0u32);
}

#[test]
fn try_into() {
// `PrimitiveInteger` is not specific about the `TryInto` error type,
// only constraining that it implements `PrimitiveError`.
fn check<T: PrimitiveInteger>(x: T, ok: u32) {
check_result(x.try_into(), ok);
}
Expand Down
4 changes: 3 additions & 1 deletion src/unsigned.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::convert::Infallible;

use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveSigned};

/// Trait for all primitive [unsigned integer types], including the supertraits
Expand Down Expand Up @@ -32,7 +34,7 @@ use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveSigned};
/// assert_eq!(gcd::<u16>(1071, 462), 21);
/// assert_eq!(gcd::<u32>(6_700_417, 2_147_483_647), 1);
/// ```
pub trait PrimitiveUnsigned: PrimitiveInteger + From<u8> {
pub trait PrimitiveUnsigned: PrimitiveInteger + From<u8> + TryFrom<u8, Error = Infallible> {
/// The signed integer type used by methods like
/// [`checked_add_signed`][Self::checked_add_signed].
type Signed: PrimitiveSigned;
Expand Down