Skip to content

Commit 25a622a

Browse files
committed
add conversion between integer types and bool through the TryFrom trait.
1 parent 2954cb5 commit 25a622a

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/libcore/num/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4206,6 +4206,25 @@ macro_rules! try_from_both_bounded {
42064206
)*}
42074207
}
42084208

4209+
macro_rules! try_bool_from {
4210+
($($source:ty),*) => {$(
4211+
#[unstable(feature = "try_from", issue = "33417")]
4212+
impl TryFrom<$source> for bool {
4213+
type Error = TryFromIntError;
4214+
4215+
#[inline]
4216+
fn try_from(u: $source) -> Result<bool, TryFromIntError> {
4217+
if u == 1 {
4218+
Ok(true)
4219+
} else if u == 0 {
4220+
Ok(false)
4221+
} else {
4222+
Err(TryFromIntError(()))
4223+
}
4224+
}
4225+
}
4226+
)*}
4227+
}
42094228
macro_rules! rev {
42104229
($mac:ident, $source:ty, $($target:ty),*) => {$(
42114230
$mac!($target, $source);
@@ -4223,6 +4242,9 @@ try_from_both_bounded!(i32, i16, i8);
42234242
try_from_both_bounded!(i64, i32, i16, i8);
42244243
try_from_both_bounded!(i128, i64, i32, i16, i8);
42254244

4245+
// Integer -> Boolean
4246+
try_bool_from! { u8, u16, u32, u64, u128, i8, i16, i32, i64, i128 }
4247+
42264248
// unsigned-to-signed
42274249
try_from_upper_bounded!(u8, i8);
42284250
try_from_upper_bounded!(u16, i8, i16);

src/libcore/tests/num/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,37 @@ assume_usize_width! {
527527
test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
528528
}
529529

530+
/// Conversions to bool is lossy.
531+
/// This checks that we only accept 1 for true and 0 for false.
532+
macro_rules! test_impl_try_bool_from_integers {
533+
($fn_name:ident, $source: ty) => {
534+
#[test]
535+
fn $fn_name() {
536+
let max = <$source>::max_value();
537+
let min = <$source>::min_value();
538+
let one: $source = 1;
539+
let zero: $source = 0;
540+
assert!(<bool as TryFrom<$source>>::try_from(max).is_err());
541+
if min != zero {
542+
assert!(<bool as TryFrom<$source>>::try_from(min).is_err());
543+
}
544+
assert_eq!(true, <bool as TryFrom<$source>>::try_from(one).unwrap());
545+
assert_eq!(false, <bool as TryFrom<$source>>::try_from(zero).unwrap());
546+
}
547+
}
548+
}
549+
550+
test_impl_try_bool_from_integers! { test_try_bool_from_u8, u8 }
551+
test_impl_try_bool_from_integers! { test_try_bool_from_u16, u16 }
552+
test_impl_try_bool_from_integers! { test_try_bool_from_u32, u32 }
553+
test_impl_try_bool_from_integers! { test_try_bool_from_u64, u64 }
554+
test_impl_try_bool_from_integers! { test_try_bool_from_u128, u128 }
555+
test_impl_try_bool_from_integers! { test_try_bool_from_i8, i8 }
556+
test_impl_try_bool_from_integers! { test_try_bool_from_i16, i16 }
557+
test_impl_try_bool_from_integers! { test_try_bool_from_i32, i32 }
558+
test_impl_try_bool_from_integers! { test_try_bool_from_i64, i64 }
559+
test_impl_try_bool_from_integers! { test_try_bool_from_i128, i128 }
560+
530561
macro_rules! test_float {
531562
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => { mod $modname {
532563
// FIXME(nagisa): these tests should test for sign of -0.0

0 commit comments

Comments
 (0)