reactive_graph/owner/
storage.rsuse super::arena::{Arena, NodeId};
use send_wrapper::SendWrapper;
pub trait StorageAccess<T> {
fn as_borrowed(&self) -> &T;
fn into_taken(self) -> T;
}
impl<T> StorageAccess<T> for T {
fn as_borrowed(&self) -> &T {
self
}
fn into_taken(self) -> T {
self
}
}
impl<T> StorageAccess<T> for SendWrapper<T> {
fn as_borrowed(&self) -> &T {
self
}
fn into_taken(self) -> T {
self.take()
}
}
pub trait Storage<T>: Send + Sync + 'static {
type Wrapped: StorageAccess<T> + Send + Sync + 'static;
fn wrap(value: T) -> Self::Wrapped;
fn try_with<U>(node: NodeId, fun: impl FnOnce(&T) -> U) -> Option<U>;
fn try_with_mut<U>(
node: NodeId,
fun: impl FnOnce(&mut T) -> U,
) -> Option<U>;
fn try_set(node: NodeId, value: T) -> Option<T>;
}
#[derive(Debug, Copy, Clone)]
pub struct SyncStorage;
impl<T> Storage<T> for SyncStorage
where
T: Send + Sync + 'static,
{
type Wrapped = T;
#[inline(always)]
fn wrap(value: T) -> Self::Wrapped {
value
}
fn try_with<U>(node: NodeId, fun: impl FnOnce(&T) -> U) -> Option<U> {
Arena::with(|arena| {
let m = arena.get(node);
m.and_then(|n| n.downcast_ref::<T>()).map(fun)
})
}
fn try_with_mut<U>(
node: NodeId,
fun: impl FnOnce(&mut T) -> U,
) -> Option<U> {
Arena::with_mut(|arena| {
let m = arena.get_mut(node);
m.and_then(|n| n.downcast_mut::<T>()).map(fun)
})
}
fn try_set(node: NodeId, value: T) -> Option<T> {
Arena::with_mut(|arena| {
let m = arena.get_mut(node);
match m.and_then(|n| n.downcast_mut::<T>()) {
Some(inner) => {
*inner = value;
None
}
None => Some(value),
}
})
}
}
#[derive(Debug, Copy, Clone)]
pub struct LocalStorage;
impl<T> Storage<T> for LocalStorage
where
T: 'static,
{
type Wrapped = SendWrapper<T>;
fn wrap(value: T) -> Self::Wrapped {
SendWrapper::new(value)
}
fn try_with<U>(node: NodeId, fun: impl FnOnce(&T) -> U) -> Option<U> {
Arena::with(|arena| {
let m = arena.get(node);
m.and_then(|n| n.downcast_ref::<SendWrapper<T>>())
.map(|inner| fun(inner))
})
}
fn try_with_mut<U>(
node: NodeId,
fun: impl FnOnce(&mut T) -> U,
) -> Option<U> {
Arena::with_mut(|arena| {
let m = arena.get_mut(node);
m.and_then(|n| n.downcast_mut::<SendWrapper<T>>())
.map(|inner| fun(&mut *inner))
})
}
fn try_set(node: NodeId, value: T) -> Option<T> {
Arena::with_mut(|arena| {
let m = arena.get_mut(node);
match m.and_then(|n| n.downcast_mut::<SendWrapper<T>>()) {
Some(inner) => {
*inner = SendWrapper::new(value);
None
}
None => Some(value),
}
})
}
}