1#![deny(clippy::unwrap_used, clippy::expect_used)]
44#![warn(clippy::all, clippy::nursery)]
45
46use std::{
47 cell::OnceCell,
48 rc::{Rc, Weak},
49};
50
51use thiserror::Error;
52
53#[derive(Error, Debug)]
55#[non_exhaustive]
56pub enum DeferredError {
57 #[error("Cannot initialize Deferred twice!")]
58 DuplicateInitialization(),
59 #[error("Cannot use uninitialized value!")]
60 NotInitializedError(),
61}
62
63#[derive(Debug, Clone)]
67pub struct Deferred<T>(OnceCell<Weak<T>>);
68
69impl<T> Default for Deferred<T> {
70 fn default() -> Self {
71 Self(OnceCell::new())
72 }
73}
74
75impl<T> Deferred<T> {
76 pub fn try_get(&self) -> Result<Rc<T>, DeferredError> {
77 self.0
78 .get()
79 .ok_or(DeferredError::NotInitializedError())?
80 .upgrade()
81 .ok_or(DeferredError::NotInitializedError())
82 }
83 #[must_use]
84 pub fn get(&self) -> Rc<T> {
85 #[allow(clippy::expect_used)]
86 self.try_get().expect("Deferred value is not yet set!")
87 }
88 #[inline]
89 pub fn is_ready(&self) -> bool {
90 self.0.get().is_some()
91 }
92}
93
94#[derive(Debug, Clone)]
111pub struct SetOnce<'a, T>(&'a Deferred<T>);
112
113impl<'a, T> SetOnce<'a, T> {
114 pub const fn from(cell: &'a Deferred<T>) -> Self {
115 Self(cell)
116 }
117 pub fn try_set(&self, value: &Rc<T>) -> Result<(), DeferredError> {
118 self.0
119 .0
120 .set(Rc::downgrade(value))
121 .map_err(|_| DeferredError::DuplicateInitialization())
122 }
123 #[inline]
124 pub fn can_set(&self) -> bool {
125 self.0.0.get().is_none()
126 }
127}
128
129pub trait DeferredIteratorExt<T>: Iterator<Item = Deferred<T>> + Sized {
131 fn get_deferred(self) -> impl Iterator<Item = Rc<T>> {
136 self.map(|d| d.get())
137 }
138 fn try_get_deferred(self) -> impl Iterator<Item = Result<Rc<T>, DeferredError>> {
140 self.map(|d| d.try_get())
141 }
142}
143
144impl<T, I> DeferredIteratorExt<T> for I where I: Iterator<Item = Deferred<T>> {}
145
146#[allow(clippy::unwrap_used)]
148#[cfg(test)]
149mod test {
150 use super::*;
151
152 #[derive(Debug, Clone)]
153 struct Node {
154 value: String,
155 neighbors: Vec<Deferred<Node>>,
156 }
157 impl Node {
158 fn new(value: &str, n_neighbors: usize) -> Rc<Self> {
159 Rc::new(Self {
160 value: value.into(),
161 neighbors: (0..n_neighbors)
162 .map(|_| Deferred::default())
163 .collect::<Vec<_>>(),
164 })
165 }
166 }
167
168 fn make_cyclic_graph() -> Vec<Rc<Node>> {
169 let center = Node::new("Center", 4);
177 let north = Node::new("North", 3);
178 let east = Node::new("East", 3);
179 let south = Node::new("South", 3);
180 let west = Node::new("West", 3);
181
182 SetOnce::from(¢er.neighbors[0]).try_set(&north).unwrap();
183 SetOnce::from(¢er.neighbors[1]).try_set(&west).unwrap();
184 SetOnce::from(¢er.neighbors[2]).try_set(&south).unwrap();
185 SetOnce::from(¢er.neighbors[3]).try_set(&east).unwrap();
186
187 SetOnce::from(&north.neighbors[0]).try_set(&west).unwrap();
188 SetOnce::from(&north.neighbors[1]).try_set(¢er).unwrap();
189 SetOnce::from(&north.neighbors[2]).try_set(&east).unwrap();
190
191 SetOnce::from(&west.neighbors[0]).try_set(&north).unwrap();
192 SetOnce::from(&west.neighbors[1]).try_set(&south).unwrap();
193 SetOnce::from(&west.neighbors[2]).try_set(¢er).unwrap();
194
195 SetOnce::from(&south.neighbors[0]).try_set(¢er).unwrap();
196 SetOnce::from(&south.neighbors[1]).try_set(&west).unwrap();
197 SetOnce::from(&south.neighbors[2]).try_set(&east).unwrap();
198
199 SetOnce::from(&east.neighbors[0]).try_set(&north).unwrap();
200 SetOnce::from(&east.neighbors[1]).try_set(¢er).unwrap();
201 SetOnce::from(&east.neighbors[2]).try_set(&south).unwrap();
202
203 vec![center, north, east, south, west]
204 }
205
206 #[test]
207 fn cyclic_graph() {
208 let graph = make_cyclic_graph();
209 let center = graph.first().unwrap();
210
211 assert_eq!(center.value, "Center");
212
213 let north = center.neighbors[0].get();
214 let west = north.neighbors[0].get();
215 let south = west.neighbors[1].get();
216 let east = south.neighbors[2].get();
217 let center_again = east.neighbors[1].get();
218
219 assert_eq!(north.value, "North");
220 assert_eq!(west.value, "West");
221 assert_eq!(south.value, "South");
222 assert_eq!(east.value, "East");
223 assert_eq!(center_again.value, "Center");
224 }
225 #[test]
226 fn duplicate_initialization_fails() {
227 let graph = make_cyclic_graph();
228 let center = graph.first().unwrap();
229
230 let neighbor_slot = ¢er.neighbors[0];
231 let mutator = SetOnce::from(neighbor_slot);
232 let duplicate_set = mutator.try_set(center);
233
234 assert!(
235 matches!(duplicate_set, Err(DeferredError::DuplicateInitialization())),
236 "Expected DuplicateInitialization error"
237 );
238 }
239 #[test]
240 fn uninitialized_access_fails() {
241 let uninitialized: Deferred<Node> = Deferred::default();
242 let result = uninitialized.try_get();
243
244 assert!(
245 matches!(result, Err(DeferredError::NotInitializedError())),
246 "Expected NotInitializedError"
247 );
248 }
249 #[test]
250 fn iterator_extension_works() {
251 let graph = make_cyclic_graph();
252 let center = graph.first().unwrap();
253
254 let values: Vec<_> = center
255 .neighbors
256 .clone()
257 .into_iter()
258 .get_deferred()
259 .map(|rc| rc.value.clone())
260 .collect();
261
262 assert_eq!(values, vec!["North", "West", "South", "East"]);
263 }
264 #[test]
265 fn deferred_state_checking() {
266 let graph = make_cyclic_graph();
267 let center = graph.first().unwrap();
268 let neighbor = ¢er.neighbors[0];
269
270 assert!(neighbor.is_ready());
271 let m = SetOnce::from(neighbor);
272 assert!(!m.can_set());
273 }
274}