1pub trait Run: Sized {
4 fn run<T>(&self, closure: impl FnOnce(&Self) -> T) -> T;
6
7 fn run_mut<T>(&mut self, closure: impl FnOnce(&mut Self) -> T) -> T;
9
10 fn try_run<T, E>(&self, closure: impl FnOnce(&Self) -> Result<T, E>) -> Result<T, E>;
12
13 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}