pub trait OptionUtils<T> {
fn inner_mut<F>(&mut self, f: F)
where
F: FnOnce(&mut T);
fn map_into<R>(self) -> Option<R>
where
Self: Sized,
T: Into<R>;
fn try_map_into<R, E>(self) -> Result<Option<R>, E>
where
Self: Sized,
T: TryInto<R, Error = E>;
}
impl<T> OptionUtils<T> for Option<T> {
fn inner_mut<F>(&mut self, f: F)
where
F: FnOnce(&mut T),
{
if let Some(inner) = self.as_mut() {
f(inner);
}
}
fn try_map_into<R, E>(self) -> Result<Option<R>, E>
where
Self: Sized,
T: TryInto<R, Error = E>,
{
self.map(TryInto::try_into).transpose()
}
fn map_into<R>(self) -> Option<R>
where
Self: Sized,
T: Into<R>,
{
self.map(Into::into)
}
}
#[cfg(test)]
mod test {
use std::path::{Path, PathBuf};
use super::*;
use anyhow::Result;
#[test]
fn test_inner_mut() -> Result<()> {
let mut x = Some("Hello world".to_owned());
x.inner_mut(|s| s.push('!'));
assert_eq!(x, Some("Hello world!".to_owned()));
Ok(())
}
#[test]
fn test_map_into() -> Result<()> {
let path = Some("hey");
let path: Option<PathBuf> = path.map_into();
assert_eq!(path, Some(Path::new("hey").to_owned()));
Ok(())
}
#[test]
fn test_map_try_into() -> Result<()> {
let num = Some(10_u64);
let num: Option<u8> = num.try_map_into()?;
assert_eq!(num, Some(10_u8));
Ok(())
}
}