thedes_tui_core/
mutation.rs

1use std::fmt;
2
3pub trait Mutable: Send + Sync {
4    type Error: std::error::Error + Send + Sync;
5}
6
7pub trait Mutation<T>: fmt::Debug + Send + Sync + 'static
8where
9    T: Mutable,
10{
11    fn mutate(self, target: T) -> Result<T, T::Error>;
12}
13
14impl<M, T> Mutation<T> for Box<M>
15where
16    M: BoxedMutation<T> + ?Sized,
17    T: Mutable,
18{
19    fn mutate(self, target: T) -> Result<T, <T as Mutable>::Error> {
20        self.mutate_boxed(target)
21    }
22}
23
24pub trait BoxedMutation<T>: Mutation<T>
25where
26    T: Mutable,
27{
28    fn mutate_boxed(self: Box<Self>, target: T) -> Result<T, T::Error>;
29}
30
31impl<M, T> BoxedMutation<T> for M
32where
33    M: Mutation<T>,
34    T: Mutable,
35{
36    fn mutate_boxed(
37        self: Box<Self>,
38        target: T,
39    ) -> Result<T, <T as Mutable>::Error> {
40        (*self).mutate(target)
41    }
42}
43
44pub trait MutationExt<T>: Mutation<T>
45where
46    T: Mutable,
47{
48    fn then<N>(self, after: N) -> Then<Self, N>
49    where
50        Self: Sized,
51        N: Mutation<T>,
52    {
53        Then { before: self, after }
54    }
55}
56
57impl<M, T> MutationExt<T> for M
58where
59    T: Mutable,
60    M: Mutation<T>,
61{
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
65pub struct Then<M, N> {
66    before: M,
67    after: N,
68}
69
70impl<M, N, T> Mutation<T> for Then<M, N>
71where
72    T: Mutable,
73    M: Mutation<T>,
74    N: Mutation<T>,
75{
76    fn mutate(self, target: T) -> Result<T, T::Error> {
77        self.after.mutate(self.before.mutate(target)?)
78    }
79}
80
81#[derive(Clone, Copy)]
82pub struct MutationFn<F>(pub F);
83
84impl<F> fmt::Debug for MutationFn<F> {
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        f.debug_tuple("MutationFn").field(&(&self.0 as *const F)).finish()
87    }
88}
89
90impl<F, T> Mutation<T> for MutationFn<F>
91where
92    T: Mutable,
93    F: FnOnce(T) -> Result<T, T::Error> + Send + Sync + 'static,
94{
95    fn mutate(self, target: T) -> Result<T, T::Error> {
96        (self.0)(target)
97    }
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
101pub struct Id;
102
103impl<T> Mutation<T> for Id
104where
105    T: Mutable,
106{
107    fn mutate(self, target: T) -> Result<T, T::Error> {
108        Ok(target)
109    }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
113pub struct Set<T>(pub T);
114
115impl<T> Mutation<T> for Set<T>
116where
117    T: Mutable + fmt::Debug + 'static,
118{
119    fn mutate(self, _target: T) -> Result<T, T::Error> {
120        let Set(output) = self;
121        Ok(output)
122    }
123}