wasm_cache/
value.rs

1//! Dynamic values.
2//!
3//! This module contains a dynamic value type that is agnostic over the storage container,
4//! [`Value`]. It also contains aliases and implementations for [`RcValue`] and [`ArcValue`], which
5//! use the [`Rc`] and [`Arc`] reference-counted containers, respectively.
6use std::{any::Any, rc::Rc, sync::Arc};
7
8/// Dynamic value.
9///
10/// Cache values are dynamic, but need to be able to be cast into a concrete type. The [`Value`]
11/// type helps here. By default, it contains a `dyn Any`, so is able to store any type of data. It
12/// is able to be cast into a concrete type. It also contains as state the validity of the type.
13#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct Value<T> {
15    /// Valid means the data is usable.
16    valid: bool,
17    data: Option<T>,
18}
19
20pub type RcValue<V = dyn Any> = Value<Rc<V>>;
21pub type ArcValue<V = dyn Any + Send + Sync> = Value<Arc<V>>;
22
23impl Value<Rc<dyn Any>> {
24    pub fn downcast<T: 'static>(self) -> Option<Value<Rc<T>>> {
25        let value = Value {
26            valid: self.valid,
27            data: match self.data {
28                None => None,
29                Some(data) => Some(data.downcast::<T>().ok()?),
30            },
31        };
32        Some(value)
33    }
34}
35
36impl Value<Arc<dyn Any + Send + Sync>> {
37    pub fn downcast<T: Any + Send + Sync>(self) -> Option<Value<Arc<T>>> {
38        let value = Value {
39            valid: self.valid,
40            data: match self.data {
41                None => None,
42                Some(data) => Some(data.downcast::<T>().ok()?),
43            },
44        };
45        Some(value)
46    }
47}
48
49impl<T> Default for Value<T> {
50    fn default() -> Self {
51        Self {
52            valid: false,
53            data: None,
54        }
55    }
56}
57
58impl<T> Value<T> {
59    /// Create new value with the given data.
60    pub fn new(data: T) -> Self {
61        Self {
62            data: Some(data),
63            valid: true,
64        }
65    }
66
67    /// Return an option with a reference to the data.
68    pub fn data(&self) -> Option<&T> {
69        self.data.as_ref()
70    }
71
72    /// Determine if this data is valid.
73    pub fn valid(&self) -> bool {
74        self.valid
75    }
76
77    /// Invalidate this data.
78    pub fn invalidate(&mut self) {
79        self.valid = false;
80    }
81}