pub trait Apply: Sized {
fn apply(&self, closure: impl FnOnce(&Self) -> ()) -> &Self;
fn apply_mut(&mut self, closure: impl FnOnce(&mut Self) -> ()) -> &mut Self;
fn try_apply<E>(&self, closure: impl FnOnce(&Self) -> Result<(), E>) -> Result<&Self, E>;
fn try_apply_mut<E>(&mut self, closure: impl FnOnce(&mut Self) -> Result<(), E>) -> Result<&mut Self, E>;
}
impl<A: Sized> Apply for A {
#[inline(always)]
fn apply(&self, closure: impl FnOnce(&Self) -> ()) -> &Self {
closure(self);
self
}
#[inline(always)]
fn apply_mut(&mut self, closure: impl FnOnce(&mut Self) -> ()) -> &mut Self {
closure(self);
self
}
#[inline(always)]
fn try_apply<E>(&self, closure: impl FnOnce(&Self) -> Result<(), E>) -> Result<&Self, E> {
closure(&self)?;
Ok(self)
}
#[inline(always)]
fn try_apply_mut<E>(&mut self, closure: impl FnOnce(&mut Self) -> Result<(), E>) -> Result<&mut Self, E> {
closure(self)?;
Ok(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn apply_works() {
let mut x = 14;
let y = 14.apply(|_| x += 14);
assert_eq!(x + y, 42);
}
#[test]
fn apply_mut_works() {
let mut binding = String::from("one two");
let x = binding.apply_mut(|x| x.truncate(3));
assert_eq!(x, "one");
}
#[test]
fn try_apply_works() {
let x: Result<&i32, ()> = 42.try_apply(|_| Ok(()));
assert_eq!(x, Ok(&42));
let y = 0.try_apply(|_| Err("error"));
assert_eq!(y, Err("error"));
}
#[test]
fn try_apply_mut_works() {
let mut binding = String::from("one two");
let x: Result<&mut String, ()> = binding.try_apply_mut(|x| {
x.truncate(3);
Ok(())
});
assert_eq!(x, Ok(&mut String::from("one")));
let y = binding.try_apply_mut(|_| Err("error"));
assert_eq!(y, Err("error"));
}
}