micro_tower/util/
borrow.rs1use std::ops::{Deref, DerefMut};
2use std::sync::{Arc, Mutex};
3
4pub struct Cell<T> {
6 inner: Arc<Mutex<Option<T>>>,
7}
8
9pub struct Borrowed<T> {
11 ret: Arc<Mutex<Option<T>>>,
12 value: Option<T>,
13}
14
15impl<T> Cell<T> {
16 pub fn new(value: T) -> Self {
17 Self {
18 inner: Arc::new(Mutex::new(Some(value))),
19 }
20 }
21
22 #[must_use]
29 pub fn is_available(&self) -> bool {
30 self.inner.lock().unwrap().is_some()
31 }
32
33 #[must_use]
39 pub fn try_borrow(&self) -> Option<Borrowed<T>> {
40 self.inner.lock().unwrap().take().map(|value| Borrowed {
41 ret: self.inner.clone(),
42 value: Some(value),
43 })
44 }
45}
46
47impl<T: Clone> Cell<T> {
48 #[must_use]
50 pub fn fork(&self) -> Option<Cell<T>> {
51 if let Some(inner) = self.try_borrow() {
52 return Some(Cell::new(inner.clone()));
53 }
54 None
55 }
56}
57
58impl<T> Drop for Borrowed<T> {
59 fn drop(&mut self) {
60 let value = self.value.take().expect("can only be dropped once");
61 self.ret.lock().unwrap().replace(value);
62 }
63}
64
65impl<T> Deref for Borrowed<T> {
66 type Target = T;
67
68 fn deref(&self) -> &Self::Target {
69 self.value.as_ref().expect("already dropped")
70 }
71}
72
73impl<T> DerefMut for Borrowed<T> {
74 fn deref_mut(&mut self) -> &mut Self::Target {
75 self.value.as_mut().expect("already dropped")
76 }
77}