scope_functions/
run.rs

1//! Defines several scope functions which take `Self` as an argument and return a value.
2
3pub trait Run: Sized {
4    /// Calls the specified `closure` with `Self` as an argument and returns its result.
5    fn run<T>(&self, closure: impl FnOnce(&Self) -> T) -> T;
6
7    /// Calls the specified `closure` with mutable `Self` as an argument and returns its result.
8    fn run_mut<T>(&mut self, closure: impl FnOnce(&mut Self) -> T) -> T;
9
10    /// Calls the specified `closure` with `Self` as an argument and returns a `Result`.
11    fn try_run<T, E>(&self, closure: impl FnOnce(&Self) -> Result<T, E>) -> Result<T, E>;
12
13    /// Calls the specified `closure` with mutable `Self` as an argument and returns a `Result`.
14    fn try_run_mut<T, E>(&mut self, closure: impl FnOnce(&mut Self) -> Result<T, E>) -> Result<T, E>;
15}
16
17impl<A: Sized> Run for A {
18    #[inline(always)]
19    fn run<T>(&self, closure: impl FnOnce(&Self) -> T) -> T {
20        closure(self)
21    }
22
23    #[inline(always)]
24    fn run_mut<T>(&mut self, closure: impl FnOnce(&mut Self) -> T) -> T {
25        closure(self)
26    }
27
28    #[inline(always)]
29    fn try_run<T, E>(&self, closure: impl FnOnce(&Self) -> Result<T, E>) -> Result<T, E> {
30        closure(self)
31    }
32
33    #[inline(always)]
34    fn try_run_mut<T, E>(&mut self, closure: impl FnOnce(&mut Self) -> Result<T, E>) -> Result<T, E> {
35        closure(self)
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use std::ops::SubAssign;
42
43    use super::*;
44
45    #[test]
46    fn run_works() {
47        let x = 21;
48        let y = x.run(|x| x + 21);
49
50        assert_eq!(y, 42);
51    }
52
53    #[test]
54    fn run_mut_works() {
55        let x = &mut 28;
56        let y = 14.run_mut(|_| {
57            x.sub_assign(14);
58            28
59        });
60        let z = *x + y;
61
62        assert_eq!(z, 42);
63    }
64
65    #[test]
66    fn try_run_works() {
67        let x: Result<i32, ()> = 42.try_run(|x| Ok(*x));
68        assert_eq!(x, Ok(42));
69
70        let y: Result<(), &str> = 0.try_run(|_| Err("error"));
71        assert_eq!(y, Err("error"));
72    }
73
74    #[test]
75    fn try_run_mut_works() {
76        let x: Result<i32, ()> = 42.try_run_mut(|x| Ok(*x));
77        assert_eq!(x, Ok(42));
78
79        let y: Result<(), &str> = 0.try_run_mut(|_| Err("error"));
80        assert_eq!(y, Err("error"));
81    }
82}