futures_signals_ext/
option.rs

1use std::ops::Deref;
2
3use futures_signals::signal::{Mutable, Signal};
4
5use crate::MutableExt;
6
7#[derive(Debug)]
8pub struct MutableOption<T>(Mutable<Option<T>>);
9
10impl<T> Default for MutableOption<T> {
11    fn default() -> Self {
12        Self(Mutable::new(None))
13    }
14}
15
16impl<T> Clone for MutableOption<T> {
17    fn clone(&self) -> Self {
18        Self(self.0.clone())
19    }
20}
21
22impl<T> Deref for MutableOption<T> {
23    type Target = Mutable<Option<T>>;
24
25    fn deref(&self) -> &Self::Target {
26        &self.0
27    }
28}
29
30impl<T> MutableOption<T> {
31    pub fn new(value: Option<T>) -> Self {
32        Self(Mutable::new(value))
33    }
34
35    pub fn new_some(value: T) -> Self {
36        Self(Mutable::new(Some(value)))
37    }
38
39    pub fn new_default() -> Self
40    where
41        T: Default,
42    {
43        Self(Mutable::new(Some(T::default())))
44    }
45
46    pub fn is_none(&self) -> bool {
47        self.0.lock_ref().is_none()
48    }
49
50    pub fn is_some(&self) -> bool {
51        self.0.lock_ref().is_some()
52    }
53
54    pub fn take(self) -> Option<T> {
55        self.0.take()
56    }
57
58    pub fn take_if<F>(&self, mut f: F) -> Option<T>
59    where
60        F: FnMut(&T) -> bool,
61    {
62        let mut current = self.0.lock_mut();
63        match &*current {
64            Some(current_value) if f(current_value) => current.take(),
65            _ => None,
66        }
67    }
68
69    pub fn take_if_value(&self, value: &T) -> Option<T>
70    where
71        T: PartialEq,
72    {
73        self.take_if(|current| current == value)
74    }
75
76    pub fn as_mutable(&self) -> Mutable<Option<T>> {
77        self.0.clone()
78    }
79
80    pub fn inspect_some<F>(&self, f: F)
81    where
82        F: FnOnce(&T),
83    {
84        if let Some(lock) = self.0.lock_ref().as_ref() {
85            f(lock);
86        }
87    }
88
89    pub fn inspect_some_mut<F>(&self, f: F)
90    where
91        F: FnOnce(&mut T),
92    {
93        if let Some(lock) = self.0.lock_mut().as_mut() {
94            f(lock);
95        }
96    }
97
98    pub fn map<F>(&self, f: impl FnOnce(&T) -> F) -> Option<F> {
99        self.0.lock_ref().as_ref().map(f)
100    }
101
102    pub fn map_or<U>(&self, f: impl FnOnce(&T) -> U, default: U) -> U {
103        self.map(f).unwrap_or(default)
104    }
105
106    pub fn map_or_else<U, D>(&self, f: impl FnOnce(&T) -> U, default: D) -> U
107    where
108        D: FnOnce() -> U,
109    {
110        self.map(f).unwrap_or_else(default)
111    }
112
113    pub fn map_or_default<U>(&self, f: impl FnOnce(&T) -> U) -> U
114    where
115        U: Default,
116    {
117        self.map(f).unwrap_or_default()
118    }
119
120    pub fn and_then<U>(&self, f: impl FnOnce(&T) -> Option<U>) -> Option<U> {
121        self.0.lock_ref().as_ref().and_then(f)
122    }
123
124    pub fn signal_some_default(&self) -> impl Signal<Item = T> + use<T>
125    where
126        T: Default + Copy,
127    {
128        self.signal_map_some_default(|v| *v)
129    }
130
131    pub fn signal_cloned_some_default(&self) -> impl Signal<Item = T> + use<T>
132    where
133        T: Default + Clone,
134    {
135        self.signal_map_some_default(|v| v.clone())
136    }
137
138    pub fn signal_map<F, U>(&self, mut f: F) -> impl Signal<Item = U> + use<T, F, U>
139    where
140        F: FnMut(Option<&T>) -> U,
141    {
142        self.0.signal_ref(move |v| f(v.as_ref()))
143    }
144
145    pub fn signal_map_some<F, U>(&self, mut f: F) -> impl Signal<Item = Option<U>> + use<T, F, U>
146    where
147        F: FnMut(&T) -> U,
148    {
149        self.0.signal_ref(move |v| v.as_ref().map(&mut f))
150    }
151
152    pub fn signal_and_then_some<F, U>(
153        &self,
154        mut f: F,
155    ) -> impl Signal<Item = Option<U>> + use<T, F, U>
156    where
157        F: FnMut(&T) -> Option<U>,
158    {
159        self.0.signal_ref(move |v| v.as_ref().and_then(&mut f))
160    }
161
162    pub fn signal_and_then_some_or<F, U>(
163        &self,
164        mut f: F,
165        default: U,
166    ) -> impl Signal<Item = U> + use<T, F, U>
167    where
168        F: FnMut(&T) -> Option<U>,
169        U: Clone,
170    {
171        self.0.signal_ref(move |v| {
172            v.as_ref()
173                .and_then(&mut f)
174                .unwrap_or_else(|| default.clone())
175        })
176    }
177
178    pub fn signal_and_then_some_or_else<F, D, U>(
179        &self,
180        mut f: F,
181        default: D,
182    ) -> impl Signal<Item = U> + use<T, F, D, U>
183    where
184        F: FnMut(&T) -> Option<U>,
185        D: FnOnce() -> U + Clone,
186    {
187        self.0
188            .signal_ref(move |v| v.as_ref().and_then(&mut f).unwrap_or_else(default.clone()))
189    }
190
191    pub fn signal_map_some_or<F, U>(
192        &self,
193        mut f: F,
194        default: U,
195    ) -> impl Signal<Item = U> + use<T, F, U>
196    where
197        F: FnMut(&T) -> U,
198        U: Clone,
199    {
200        self.0
201            .signal_ref(move |v| v.as_ref().map(&mut f).unwrap_or(default.clone()))
202    }
203
204    pub fn signal_map_some_or_else<F, D, U>(
205        &self,
206        mut f: F,
207        default: D,
208    ) -> impl Signal<Item = U> + use<T, F, D, U>
209    where
210        F: FnMut(&T) -> U,
211        D: FnOnce() -> U + Clone,
212    {
213        self.0
214            .signal_ref(move |v| v.as_ref().map(&mut f).unwrap_or_else(default.clone()))
215    }
216
217    pub fn signal_map_some_default<F, U>(&self, mut f: F) -> impl Signal<Item = U> + use<T, F, U>
218    where
219        F: FnMut(&T) -> U,
220        U: Default,
221    {
222        self.0
223            .signal_ref(move |v| v.as_ref().map(&mut f).unwrap_or_default())
224    }
225}