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 m = arena.get(node);
140 m.and_then(|n| n.downcast_ref::<SendWrapper<T>>())
141 .map(|inner| fun(inner))
142 })
143 }
144
145 fn try_with_mut<U>(
146 node: NodeId,
147 fun: impl FnOnce(&mut T) -> U,
148 ) -> Option<U> {
149 Arena::with_mut(|arena| {
150 let m = arena.get_mut(node);
151 m.and_then(|n| n.downcast_mut::<SendWrapper<T>>())
152 .map(|inner| fun(&mut *inner))
153 })
154 }
155
156 fn try_set(node: NodeId, value: T) -> Option<T> {
157 Arena::with_mut(|arena| {
158 let m = arena.get_mut(node);
159 match m.and_then(|n| n.downcast_mut::<SendWrapper<T>>()) {
160 Some(inner) => {
161 *inner = SendWrapper::new(value);
162 None
163 }
164 None => Some(value),
165 }
166 })
167 }
168
169 fn take(node: NodeId) -> Option<T> {
170 Arena::with_mut(|arena| {
171 let m = arena.remove(node)?;
172 match m.downcast::<SendWrapper<T>>() {
173 Ok(inner) => Some(inner.take()),
174 Err(_) => None,
175 }
176 })
177 }
178}