scsys_traits/ops/
apply.rs

1/*
2    appellation: map <module>
3    authors: @FL03
4*/
5/// [`Apply`] is a trait that allows for mapping over a reference to a type `T` by applying a
6/// function [`F`](FnOnce) to it, producing a new type `U`. The result is wrapped in a
7/// container type defined by the implementor of the trait.
8pub trait Apply<T> {
9    /// The associated type `Cont` is a higher-kinded type that represents the container
10    /// that will hold the result of the mapping operation.
11    type Cont<_T>;
12
13    fn apply<U, F>(&self, rhs: F) -> Self::Cont<U>
14    where
15        F: FnOnce(&T) -> U;
16}
17/// A the [`ApplyOnce`] trait is similar to [`Map`], but it consumes the instance instead of
18/// borrowing it;
19pub trait ApplyOnce<T> {
20    type Cont<_T>;
21
22    fn apply_once<U, F>(self, rhs: F) -> Self::Cont<U>
23    where
24        F: FnOnce(T) -> U;
25}
26/// The [`ApplyMut`] trait allows for in-place mapping of a mutable reference to a type `T`
27pub trait ApplyMut<T> {
28    type Cont<_T>;
29
30    fn apply_mut<F>(&mut self, rhs: F) -> &mut Self::Cont<T>
31    where
32        F: FnMut(&mut T);
33}
34
35/*
36 ************* Implementations *************
37*/
38
39impl<T> Apply<T> for Option<T> {
40    type Cont<U> = Option<U>;
41
42    fn apply<U, F>(&self, rhs: F) -> Self::Cont<U>
43    where
44        F: FnOnce(&T) -> U,
45    {
46        self.as_ref().map(rhs)
47    }
48}
49
50impl<T> ApplyOnce<T> for Option<T> {
51    type Cont<U> = Option<U>;
52
53    fn apply_once<U, F>(self, rhs: F) -> Self::Cont<U>
54    where
55        F: FnOnce(T) -> U,
56    {
57        self.map(rhs)
58    }
59}
60
61impl<T> ApplyMut<T> for Option<T> {
62    type Cont<U> = Option<U>;
63
64    fn apply_mut<F>(&mut self, mut rhs: F) -> &mut Self::Cont<T>
65    where
66        F: FnMut(&mut T),
67    {
68        if let Some(value) = self {
69            rhs(value);
70        }
71        self
72    }
73}