Skip to content

Commit 6ec3465

Browse files
authored
Merge pull request #17 from cuviper/specify-errors
Specify error types where possible
2 parents 6f8fa4e + 2c324ce commit 6ec3465

5 files changed

Lines changed: 68 additions & 4 deletions

File tree

src/float.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{PrimitiveNumber, PrimitiveNumberRef, PrimitiveUnsigned};
33
use core::cmp::Ordering;
44
use core::f32::consts as f32_consts;
55
use core::f64::consts as f64_consts;
6-
use core::num::FpCategory;
6+
use core::num::{FpCategory, ParseFloatError};
77

88
struct SealedToken;
99

@@ -70,6 +70,7 @@ pub trait PrimitiveFloat:
7070
+ core::convert::From<i8>
7171
+ core::convert::From<u8>
7272
+ core::ops::Neg<Output = Self>
73+
+ core::str::FromStr<Err = ParseFloatError>
7374
{
7475
/// Approximate number of significant digits in base 10.
7576
const DIGITS: u32;

src/integer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ pub trait PrimitiveInteger:
128128
+ core::ops::ShrAssign<u64>
129129
+ core::ops::ShrAssign<u128>
130130
+ core::ops::ShrAssign<usize>
131+
+ core::str::FromStr<Err = ParseIntError>
131132
+ for<'a> core::ops::BitAnd<&'a Self, Output = Self>
132133
+ for<'a> core::ops::BitAndAssign<&'a Self>
133134
+ for<'a> core::ops::BitOr<&'a Self, Output = Self>

src/signed.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::convert::Infallible;
2+
13
use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveUnsigned};
24

35
/// Trait for all primitive [signed integer types], including the supertraits [`PrimitiveInteger`]
@@ -49,7 +51,12 @@ use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveUnsigned};
4951
/// assert_eq!(extended_gcd::<i16>(1071, -462), (21, -3, -7));
5052
/// assert_eq!(extended_gcd::<i64>(6_700_417, 2_147_483_647), (1, 715_828_096, -2_233_473));
5153
/// ```
52-
pub trait PrimitiveSigned: PrimitiveInteger + From<i8> + core::ops::Neg<Output = Self> {
54+
pub trait PrimitiveSigned:
55+
PrimitiveInteger
56+
+ core::convert::From<i8>
57+
+ core::convert::TryFrom<i8, Error = Infallible>
58+
+ core::ops::Neg<Output = Self>
59+
{
5360
/// The unsigned integer type used by methods like [`abs_diff`][Self::abs_diff] and
5461
/// [`checked_add_unsigned`][Self::checked_add_unsigned].
5562
type Unsigned: PrimitiveUnsigned;

src/tests.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@
1515
extern crate alloc;
1616

1717
use alloc::boxed::Box;
18+
use core::convert::Infallible;
1819
use core::error::Error;
20+
use core::num::{ParseFloatError, ParseIntError};
1921

20-
use crate::{PrimitiveError, PrimitiveInteger, PrimitiveNumber};
22+
use crate::{
23+
PrimitiveError, PrimitiveFloat, PrimitiveInteger, PrimitiveNumber, PrimitiveSigned,
24+
PrimitiveUnsigned,
25+
};
2126

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

3843
#[test]
3944
fn parse() {
45+
// `PrimitiveNumber` is not specific about the `FromStr` error type,
46+
// only constraining that it implements `PrimitiveError`.
4047
fn check<T: PrimitiveNumber>(s: &str, ok: T) {
4148
check_result(s.parse(), ok);
4249
}
4350
check("0", 0u32);
4451
}
4552

53+
#[test]
54+
fn parse_float() {
55+
// `PrimitiveFloat` is specific about the `FromStr` error type.
56+
fn check<T: PrimitiveFloat>(s: &str, ok: T) {
57+
let r: Result<T, ParseFloatError> = s.parse();
58+
assert_eq!(r, Ok(ok));
59+
}
60+
check("0", 0f32);
61+
}
62+
63+
#[test]
64+
fn parse_int() {
65+
// `PrimitiveInteger` is specific about the `FromStr` error type.
66+
fn check<T: PrimitiveInteger>(s: &str, ok: T) {
67+
let r: Result<T, ParseIntError> = s.parse();
68+
assert_eq!(r, Ok(ok));
69+
}
70+
check("0", 0u32);
71+
}
72+
4673
#[test]
4774
fn try_from() {
75+
// `PrimitiveInteger` is not specific about the `TryFrom` error type,
76+
// only constraining that it implements `PrimitiveError`.
4877
fn check<T: PrimitiveInteger>(x: i32, ok: T) {
4978
check_result(T::try_from(x), ok);
5079
}
5180
check(0i32, 0u32);
5281
}
5382

83+
#[test]
84+
fn try_from_signed() {
85+
// `PrimitiveSigned` is specific that `TryFrom<i8>` is infallible.
86+
// (implied by `From<i8>`, but we still need an explicit constraint)
87+
fn check<T: PrimitiveSigned>(x: i8, ok: T) {
88+
let r: Result<T, Infallible> = T::try_from(x);
89+
assert_eq!(r, Ok(ok));
90+
}
91+
check(0i8, 0i32);
92+
}
93+
94+
#[test]
95+
fn try_from_unsigned() {
96+
// `PrimitiveUnsigned` is specific that `TryFrom<u8>` is infallible.
97+
// (implied by `From<u8>`, but we still need an explicit constraint)
98+
fn check<T: PrimitiveUnsigned>(x: u8, ok: T) {
99+
let r: Result<T, Infallible> = T::try_from(x);
100+
assert_eq!(r, Ok(ok));
101+
}
102+
check(0u8, 0u32);
103+
}
104+
54105
#[test]
55106
fn try_into() {
107+
// `PrimitiveInteger` is not specific about the `TryInto` error type,
108+
// only constraining that it implements `PrimitiveError`.
56109
fn check<T: PrimitiveInteger>(x: T, ok: u32) {
57110
check_result(x.try_into(), ok);
58111
}

src/unsigned.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::convert::Infallible;
2+
13
use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveSigned};
24

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

0 commit comments

Comments
 (0)