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_value(&self, value: &T) -> Option<T>
59    where
60        T: PartialEq,
61    {
62        let mut current = self.0.lock_mut();
63        match &*current {
64            Some(current_value) if current_value == value => current.take(),
65            _ => None,
66        }
67    }
68
69    pub fn as_mutable(&self) -> Mutable<Option<T>> {
70        self.0.clone()
71    }
72
73    pub fn map<F>(&self, f: impl FnOnce(&T) -> F) -> Option<F> {
74        self.0.lock_ref().as_ref().map(f)
75    }
76
77    pub fn map_or<U>(&self, f: impl FnOnce(&T) -> U, default: U) -> U {
78        self.map(f).unwrap_or(default)
79    }
80
81    pub fn map_or_else<U, D>(&self, f: impl FnOnce(&T) -> U, default: D) -> U
82    where
83        D: FnOnce() -> U,
84    {
85        self.map(f).unwrap_or_else(default)
86    }
87
88    pub fn map_or_default<U>(&self, f: impl FnOnce(&T) -> U) -> U
89    where
90        U: Default,
91    {
92        self.map(f).unwrap_or_default()
93    }
94
95    pub fn and_then<U>(&self, f: impl FnOnce(&T) -> Option<U>) -> Option<U> {
96        self.0.lock_ref().as_ref().and_then(f)
97    }
98
99    pub fn signal_some_default(&self) -> impl Signal<Item = T> + use<T>
100    where
101        T: Default + Copy,
102    {
103        self.signal_map_some_default(|v| *v)
104    }
105
106    pub fn signal_cloned_some_default(&self) -> impl Signal<Item = T> + use<T>
107    where
108        T: Default + Clone,
109    {
110        self.signal_map_some_default(|v| v.clone())
111    }
112
113    pub fn signal_map<F, U>(&self, mut f: F) -> impl Signal<Item = Option<U>> + use<T, F, U>
114    where
115        F: FnMut(Option<&T>) -> Option<U>,
116    {
117        self.0.signal_ref(move |v| f(v.as_ref()))
118    }
119
120    pub fn signal_map_some<F, U>(&self, mut f: F) -> impl Signal<Item = Option<U>> + use<T, F, U>
121    where
122        F: FnMut(&T) -> U,
123    {
124        self.0.signal_ref(move |v| v.as_ref().map(&mut f))
125    }
126
127    pub fn signal_and_then_some<F, U>(
128        &self,
129        mut f: F,
130    ) -> impl Signal<Item = Option<U>> + use<T, F, U>
131    where
132        F: FnMut(&T) -> Option<U>,
133    {
134        self.0.signal_ref(move |v| v.as_ref().and_then(&mut f))
135    }
136
137    pub fn signal_and_then_some_or<F, U>(
138        &self,
139        mut f: F,
140        default: U,
141    ) -> impl Signal<Item = U> + use<T, F, U>
142    where
143        F: FnMut(&T) -> Option<U>,
144        U: Clone,
145    {
146        self.0.signal_ref(move |v| {
147            v.as_ref()
148                .and_then(&mut f)
149                .unwrap_or_else(|| default.clone())
150        })
151    }
152
153    pub fn signal_and_then_some_or_else<F, D, U>(
154        &self,
155        mut f: F,
156        default: D,
157    ) -> impl Signal<Item = U> + use<T, F, D, U>
158    where
159        F: FnMut(&T) -> Option<U>,
160        D: FnOnce() -> U + Clone,
161    {
162        self.0
163            .signal_ref(move |v| v.as_ref().and_then(&mut f).unwrap_or_else(default.clone()))
164    }
165
166    pub fn signal_map_some_or<F, U>(
167        &self,
168        mut f: F,
169        default: U,
170    ) -> impl Signal<Item = U> + use<T, F, U>
171    where
172        F: FnMut(&T) -> U,
173        U: Clone,
174    {
175        self.0
176            .signal_ref(move |v| v.as_ref().map(&mut f).unwrap_or(default.clone()))
177    }
178
179    pub fn signal_map_some_or_else<F, D, U>(
180        &self,
181        mut f: F,
182        default: D,
183    ) -> impl Signal<Item = U> + use<T, F, D, U>
184    where
185        F: FnMut(&T) -> U,
186        D: FnOnce() -> U + Clone,
187    {
188        self.0
189            .signal_ref(move |v| v.as_ref().map(&mut f).unwrap_or_else(default.clone()))
190    }
191
192    pub fn signal_map_some_default<F, U>(&self, mut f: F) -> impl Signal<Item = U> + use<T, F, U>
193    where
194        F: FnMut(&T) -> U,
195        U: Default,
196    {
197        self.0
198            .signal_ref(move |v| v.as_ref().map(&mut f).unwrap_or_default())
199    }
200}