reactive_graph/owner/
storage.rs1use super::arena::{Arena, NodeId};
2use send_wrapper::SendWrapper;
3
4pub trait StorageAccess<T> {
6 fn as_borrowed(&self) -> &T;
8
9 fn into_taken(self) -> T;
11}
12
13impl<T> StorageAccess<T> for T {
14 fn as_borrowed(&self) -> &T {
15 self
16 }
17
18 fn into_taken(self) -> T {
19 self
20 }
21}
22
23impl<T> StorageAccess<T> for SendWrapper<T> {
24 fn as_borrowed(&self) -> &T {
25 self
26 }
27
28 fn into_taken(self) -> T {
29 self.take()
30 }
31}
32
33pub trait Storage<T>: Send + Sync + 'static {
38 type Wrapped: StorageAccess<T> + Send + Sync + 'static;
40
41 fn wrap(value: T) -> Self::Wrapped;
43
44 fn try_with<U>(node: NodeId, fun: impl FnOnce(&T) -> U) -> Option<U>;
47
48 fn try_with_mut<U>(
51 node: NodeId,
52 fun: impl FnOnce(&mut T) -> U,
53 ) -> Option<U>;
54
55 fn try_set(node: NodeId, value: T) -> Option<T>;
57
58 fn take(node: NodeId) -> Option<T>;
61}
62
63#[derive(Debug, Copy, Clone)]
65pub struct SyncStorage;
66
67impl<T> Storage<T> for SyncStorage
68where
69 T: Send + Sync + 'static,
70{
71 type Wrapped = T;
72
73 #[inline(always)]
74 fn wrap(value: T) -> Self::Wrapped {
75 value
76 }
77
78 fn try_with<U>(node: NodeId, fun: impl FnOnce(&T) -> U) -> Option<U> {
79 Arena::try_with(|arena| {
80 let m = arena.get(node);
81 m.and_then(|n| n.downcast_ref::<T>()).map(fun)
82 })
83 .flatten()
84 }
85
86 fn try_with_mut<U>(
87 node: NodeId,
88 fun: impl FnOnce(&mut T) -> U,
89 ) -> Option<U> {
90 Arena::try_with_mut(|arena| {
91 let m = arena.get_mut(node);
92 m.and_then(|n| n.downcast_mut::<T>()).map(fun)
93 })
94 .flatten()
95 }
96
97 fn try_set(node: NodeId, value: T) -> Option<T> {
98 Arena::try_with_mut(|arena| {
99 let m = arena.get_mut(node);
100 match m.and_then(|n| n.downcast_mut::<T>()) {
101 Some(inner) => {
102 *inner = value;
103 None
104 }
105 None => Some(value),
106 }
107 })
108 .flatten()
109 }
110
111 fn take(node: NodeId) -> Option<T> {
112 Arena::with_mut(|arena| {
113 let m = arena.remove(node)?;
114 match m.downcast::<T>() {
115 Ok(inner) => Some(*inner),
116 Err(_) => None,
117 }
118 })
119 }
120}
121
122#[derive(Debug, Copy, Clone)]
125pub struct LocalStorage;
126
127impl<T> Storage<T> for LocalStorage
128where
129 T: 'static,
130{
131 type Wrapped = SendWrapper<T>;
132
133 fn wrap(value: T) -> Self::Wrapped {
134 SendWrapper::new(value)
135 }
136
137 fn try_with<U>(node: NodeId, fun: impl FnOnce(&T) -> U) -> Option<U> {
138 Arena::with(|arena| {
139 let n = arena.get(node)?.downcast_ref::<SendWrapper<T>>()?;
140 if !n.valid() {
143 return None;
144 }
145 Some(fun(n))
146 })
147 }
148
149 fn try_with_mut<U>(
150 node: NodeId,
151 fun: impl FnOnce(&mut T) -> U,
152 ) -> Option<U> {
153 Arena::with_mut(|arena| {
154 let n = arena.get_mut(node)?.downcast_mut::<SendWrapper<T>>()?;
155 if !n.valid() {
156 return None;
157 }
158 Some(fun(&mut *n))
159 })
160 }
161
162 fn try_set(node: NodeId, value: T) -> Option<T> {
163 Arena::with_mut(|arena| {
164 match arena
165 .get_mut(node)
166 .and_then(|n| n.downcast_mut::<SendWrapper<T>>())
167 {
168 Some(inner) if inner.valid() => {
171 *inner = SendWrapper::new(value);
172 None
173 }
174 _ => Some(value),
175 }
176 })
177 }
178
179 fn take(node: NodeId) -> Option<T> {
180 Arena::with_mut(|arena| {
181 let valid = arena
184 .get(node)
185 .and_then(|n| n.downcast_ref::<SendWrapper<T>>())
186 .map(|inner| inner.valid());
187 if valid != Some(true) {
188 return None;
189 }
190 let m = arena.remove(node)?;
191 match m.downcast::<SendWrapper<T>>() {
192 Ok(inner) => Some(inner.take()),
193 Err(_) => None,
194 }
195 })
196 }
197}