Hi, I thought it may be worthy to add a map
function for NonZero<T>
types...
I imagine such function would be more or less like this:
pub fn map<U, F>(self, f: F) -> Option<NonZero<U>>
where
F: FnOnce(T) -> U,
{
NonZero::<U>::new(f(self.get()))
}
This would allow writing code like:
let res = NonZeroU64::new(5)?
.map(|x| x * 10)?
.map(|x| some_fn_that_does_some_calculations(x))?
.map(|x| x - 50)?;
I've tried it in the Rust Playground here: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=9eb3ea1ceb79b91b228ddc59fa7d1455
#![feature(try_blocks)]
#![feature(nonzero_internals)]
use std::num::NonZero;
use std::num::NonZeroU64;
use std::num::ZeroablePrimitive;
trait MappableNonZero<T>
where
T: ZeroablePrimitive,
{
fn map<U, F>(self, f: F) -> Option<NonZero<U>>
where
F: FnOnce(T) -> U,
U: ZeroablePrimitive;
}
impl<T> MappableNonZero<T> for NonZero<T>
where
T: ZeroablePrimitive,
{
fn map<U, F>(self, f: F) -> Option<NonZero<U>>
where
F: FnOnce(T) -> U,
U: ZeroablePrimitive,
{
NonZero::<U>::new(f(self.get()))
}
}
fn some_fn_that_does_some_calculations(x: u64) -> u64 {
// With 50u64, `res` becomes None
51u64
}
fn main() {
let res: Option<u64> = try {
NonZeroU64::new(5)?
.map(|x| x * 10)?
.map(|x| some_fn_that_does_some_calculations(x))?
.map(|x| x - 50)?
.get()
};
println!("{:?}", res);
}