scope_functions/
apply.rs

1//! Defines several scope functions that perform additional actions on `Self`.
2
3pub trait Apply: Sized {
4    /// Calls the specified `closure` with `Self` as an argument and returns `Self`.
5    fn apply(&self, closure: impl FnOnce(&Self) -> ()) -> &Self;
6
7    /// Calls the specified `closure` with mutable `Self` as an argument and returns `Self`.
8    fn apply_mut(&mut self, closure: impl FnOnce(&mut Self) -> ()) -> &mut Self;
9
10    /// Calls the specified `closure` with `Self` as an argument and returns a `Result`.
11    fn try_apply<E>(&self, closure: impl FnOnce(&Self) -> Result<(), E>) -> Result<&Self, E>;
12
13    /// Calls the specified `closure` with mutable `Self` as an argument and returns a `Result`.
14    fn try_apply_mut<E>(&mut self, closure: impl FnOnce(&mut Self) -> Result<(), E>) -> Result<&mut Self, E>;
15}
16
17impl<A: Sized> Apply for A {
18    #[inline(always)]
19    fn apply(&self, closure: impl FnOnce(&Self) -> ()) -> &Self {
20        closure(self);
21        self
22    }
23
24    #[inline(always)]
25    fn apply_mut(&mut self, closure: impl FnOnce(&mut Self) -> ()) -> &mut Self {
26        closure(self);
27        self
28    }
29
30    #[inline(always)]
31    fn try_apply<E>(&self, closure: impl FnOnce(&Self) -> Result<(), E>) -> Result<&Self, E> {
32        closure(&self)?;
33        Ok(self)
34    }
35
36    #[inline(always)]
37    fn try_apply_mut<E>(&mut self, closure: impl FnOnce(&mut Self) -> Result<(), E>) -> Result<&mut Self, E> {
38        closure(self)?;
39        Ok(self)
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn apply_works() {
49        let mut x = 14;
50        let y = 14.apply(|_| x += 14);
51
52        assert_eq!(x + y, 42);
53    }
54
55    #[test]
56    fn apply_mut_works() {
57        let mut binding = String::from("one two");
58        let x = binding.apply_mut(|x| x.truncate(3));
59
60        assert_eq!(x, "one");
61    }
62
63    #[test]
64    fn try_apply_works() {
65        let x: Result<&i32, ()> = 42.try_apply(|_| Ok(()));
66        assert_eq!(x, Ok(&42));
67
68        let y = 0.try_apply(|_| Err("error"));
69        assert_eq!(y, Err("error"));
70    }
71
72    #[test]
73    fn try_apply_mut_works() {
74        let mut binding = String::from("one two");
75
76        let x: Result<&mut String, ()> = binding.try_apply_mut(|x| {
77            x.truncate(3);
78
79            Ok(())
80        });
81        assert_eq!(x, Ok(&mut String::from("one")));
82
83        let y = binding.try_apply_mut(|_| Err("error"));
84        assert_eq!(y, Err("error"));
85    }
86}