Need to turn a 0 or 1 from a database, config file, or FFI boundary into a bool? bool::try_from does it safely — rejecting anything that isn’t 0 or 1. Stabilized in Rust 1.95.
The old way: match or panic
When you get integer flags from external sources — database columns, binary protocols, C APIs — you need to convert them to bool. Before 1.95, you’d write your own:
1
2
3
4
5
6
7
| fn int_to_bool(v: u8) -> Result<bool, String> {
match v {
0 => Ok(false),
1 => Ok(true),
other => Err(format!("invalid bool value: {other}")),
}
}
|
Or worse, you’d just do v != 0 and silently treat 42 as true, hiding data corruption.
The new way: bool::try_from
Rust 1.95 stabilizes TryFrom<{integer}> for bool across all integer types — u8, i32, u64, you name it:
1
2
3
4
5
6
7
8
9
10
11
12
13
| fn main() {
let t = bool::try_from(1u8);
let f = bool::try_from(0i32);
let e = bool::try_from(2u8);
assert_eq!(t, Ok(true));
assert_eq!(f, Ok(false));
assert!(e.is_err());
println!("{t:?}"); // Ok(true)
println!("{f:?}"); // Ok(false)
println!("{e:?}"); // Err(TryFromIntError(()))
}
|
Only 0 maps to false and 1 maps to true. Everything else returns Err(TryFromIntError). No silent coercion, no panics.
Real-world usage: parsing a config
Here’s where it shines — reading flags from external data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| use std::collections::HashMap;
fn main() {
// Simulating values from a config file or database row
let config: HashMap<&str, i64> = HashMap::from([
("verbose", 1),
("dry_run", 0),
("debug", 3), // invalid!
]);
for (key, &val) in &config {
match bool::try_from(val) {
Ok(flag) => println!("{key} = {flag}"),
Err(_) => eprintln!("warning: {key} has invalid bool value: {val}"),
}
}
}
|
Instead of silently treating 3 as true, you get a clear warning and a chance to handle bad data properly.
Why not just val != 0?
The C convention of “zero is false, everything else is true” works fine when you control the data. But when parsing untrusted input — database rows, wire protocols, config files — a value of 255 probably means something went wrong. bool::try_from catches that; != 0 hides it.
One method call, no custom helpers, no silent bugs.