Skip to main content

libsugar/
side_effect.rs

1//! Some extension functions that are convenient for side effects
2
3/// using
4/// ## Usage
5/// ```rust
6/// # use libsugar::*;
7/// let v = (1, 2);
8/// let v2 = (3, 4);
9/// using!((a, b) = v, (c, d) = v2; {
10///   println!("{} {} {} {}", a, b, c, d)
11///   # ;
12///   # assert_eq!(a, 1);
13///   # assert_eq!(b, 2);
14///   # assert_eq!(c, 3);
15///   # assert_eq!(d, 4);
16/// })
17/// ```
18/// *equivalent to*
19/// ```no_run
20/// let v = (1, 2);
21/// let v2 = (3, 4);
22/// {
23///   let (a, b) = v;
24///   let (c, d) = v2;
25///   {
26///     println!("{} {} {} {}", a, b, c, d)
27///   }
28/// }
29///   ```
30#[macro_export(local_inner_macros)]
31macro_rules! using {
32    { $($p:pat = $v:expr),* ; $b:block } => {
33        { $(let $p = $v ;)* $b }
34    };
35}
36
37/// Create an implicit variable, and make a mapping for it
38/// ## Example
39/// ```rust
40/// # use libsugar::Used;
41/// let v = 1.used(|v| { v + 1 });
42/// assert_eq!(v, 2);
43/// ```
44pub trait Used: Sized {
45    /// Create an implicit variable, and make a mapping for it
46    /// ## Example
47    /// ```rust
48    /// # use libsugar::Used;
49    /// let v = 1.used(|v| { v + 1 });
50    /// assert_eq!(v, 2);
51    /// ```
52    fn used<F: FnOnce(Self) -> R, R>(self, f: F) -> R;
53}
54impl<T> Used for T {
55    fn used<F: FnOnce(Self) -> R, R>(self, f: F) -> R {
56        f(self)
57    }
58}
59
60/// Create an implicit variable, do some extra thing, and return it
61/// ## Example
62/// ```rust
63/// # use libsugar::Also;
64/// let v = 1.also(|v| { println!("{}", v) });
65/// assert_eq!(v, 1);
66/// ```
67pub trait Also: Sized {
68    /// Create an implicit variable, do some extra thing, and return it
69    /// ## Example
70    /// ```rust
71    /// # use libsugar::Also;
72    /// let v = 1.also(|v| { println!("{}", v) });
73    /// assert_eq!(v, 1);
74    /// ```
75    fn also<F: FnOnce(&Self)>(self, f: F) -> Self;
76}
77impl<T> Also for T {
78    fn also<F: FnOnce(&Self)>(self, f: F) -> Self {
79        f(&self);
80        self
81    }
82}
83
84/// Create an implicit variable, do some extra thing, and return it
85/// ## Example
86/// ```rust
87/// # use libsugar::AlsoMut;
88/// let v = 1.also_mut(|v| {
89///     println!("{}", v);
90///     *v += 1;
91/// });
92/// assert_eq!(v, 2);
93/// ```
94pub trait AlsoMut: Sized {
95    /// Create an implicit variable, do some extra thing, and return it
96    /// ## Example
97    /// ```rust
98    /// # use libsugar::AlsoMut;
99    /// let v = 1.also_mut(|v| {
100    ///     println!("{}", v);
101    ///     *v += 1;
102    /// });
103    /// assert_eq!(v, 2);
104    /// ```
105    fn also_mut<F: FnOnce(&mut Self)>(self, f: F) -> Self;
106}
107impl<T> AlsoMut for T {
108    fn also_mut<F: FnOnce(&mut Self)>(mut self, f: F) -> Self {
109        f(&mut self);
110        self
111    }
112}
113
114/// Run function immediately 
115#[inline(always)]
116pub fn run<R>(f: impl FnOnce() -> R) -> R {
117    f()
118}