devela/sys/mem/cell/
option.rs1use crate::Cell;
7
8trait Sealed {}
10impl<T> Sealed for Cell<Option<T>> {}
11
12#[doc = crate::TAG_NAMESPACE!()]
13#[cfg_attr(feature = "nightly_doc", doc(notable_trait))]
15#[expect(private_bounds, reason = "Sealed")]
16pub trait ExtCellOption<T>: Sealed {
17 fn modify<F: FnOnce(T) -> T>(&self, func: F);
32
33 fn modify_ret<F: FnOnce(T) -> T>(&self, func: F) -> Option<T>
46 where
47 T: Clone;
48
49 fn modify_mut<R, F: FnOnce(&mut T) -> R>(&self, func: F) -> Option<R>;
69}
70
71impl<T> ExtCellOption<T> for Cell<Option<T>> {
72 fn modify<F: FnOnce(T) -> T>(&self, func: F) {
73 let mut value = self.take();
74 if let Some(v) = value.take() {
76 self.set(Some(func(v)));
77 }
78 }
79
80 fn modify_ret<F: FnOnce(T) -> T>(&self, func: F) -> Option<T>
81 where
82 T: Clone,
83 {
84 self.replace(None).inspect(|v| {
85 let new_value = func(v.clone());
86 self.set(Some(new_value));
87 })
88 }
89
90 fn modify_mut<R, F: FnOnce(&mut T) -> R>(&self, func: F) -> Option<R> {
91 if let Some(mut v) = self.take() {
92 let result = func(&mut v);
94 self.set(Some(v));
96 Some(result)
97 } else {
98 None
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_modify() {
109 let cell = Cell::new(Some(10));
110 cell.modify(|x| x + 5);
111 assert_eq!(cell.get(), Some(15));
112 }
113
114 #[test]
115 fn test_modify_with_none() {
116 let cell: Cell<Option<i32>> = Cell::new(None);
117 cell.modify(|x| x + 5);
118 assert_eq!(cell.get(), None);
119 }
120
121 #[test]
122 fn test_modify_ret() {
123 let cell = Cell::new(Some(10));
124
125 let previous_value = cell.modify_ret(|x| x * 2);
126
127 assert_eq!(previous_value, Some(10));
128 assert_eq!(cell.get(), Some(20));
129 }
130
131 #[test]
132 fn test_modify_ret_with_none() {
133 let cell: Cell<Option<i32>> = Cell::new(None);
134
135 let previous_value = cell.modify_ret(|x| x * 2);
136
137 assert_eq!(previous_value, None);
138 assert_eq!(cell.get(), None);
139 }
140
141 #[test]
142 fn test_modify_mut_previous() {
143 let cell = Cell::new(Some(10));
144
145 let result = cell.modify_mut(|x| {
146 let prev = *x;
147 *x *= 2;
148 prev
149 });
150
151 assert_eq!(result, Some(10)); assert_eq!(cell.get(), Some(20));
153 }
154 #[test]
155 fn test_modify_mut() {
156 let cell = Cell::new(Some(10));
157
158 let result = cell.modify_mut(|x| {
159 *x *= 2;
160 *x + 5
161 });
162
163 assert_eq!(result, Some(25));
164 assert_eq!(cell.get(), Some(20));
165 }
166
167 #[test]
168 fn test_modify_mut_with_none() {
169 let cell: Cell<Option<i32>> = Cell::new(None);
170
171 let result = cell.modify_mut(|x| {
172 *x *= 2;
173 *x + 5
174 });
175
176 assert_eq!(result, None);
177 assert_eq!(cell.get(), None);
178 }
179
180 #[test]
181 fn test_modify_mut_side_effect() {
182 let cell = Cell::new(Some(10));
183
184 let result = cell.modify_mut(|x| {
185 *x += 3;
186 "Done"
187 });
188
189 assert_eq!(result, Some("Done"));
190 assert_eq!(cell.get(), Some(13));
191 }
192}