Skip to main content

conjure_cp_core/representation/
store.rs

1use super::registry::get_repr_by_name;
2use super::stored::{ReprRuleStored, ReprStateStored};
3use super::types::ReprRule;
4use serde::de::{MapAccess, Visitor};
5use serde::ser::SerializeMap;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use std::collections::HashMap;
8use std::fmt;
9use std::fmt::Debug;
10
11pub struct ReprStore {
12    inner: HashMap<&'static str, Box<dyn ReprStateStored>>,
13}
14
15impl Debug for ReprStore {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        write!(f, "ReprStore")
18    }
19}
20
21impl Clone for ReprStore {
22    fn clone(&self) -> Self {
23        Self {
24            inner: self
25                .inner
26                .iter()
27                .map(|(&k, v)| (k, v.clone_box()))
28                .collect(),
29        }
30    }
31}
32
33impl PartialEq for ReprStore {
34    fn eq(&self, other: &Self) -> bool {
35        self.inner
36            .keys()
37            .zip(other.inner.keys())
38            .all(|(k1, k2)| k1 == k2)
39    }
40}
41
42impl Eq for ReprStore {}
43
44impl Default for ReprStore {
45    fn default() -> Self {
46        Self::new()
47    }
48}
49
50impl ReprStore {
51    pub fn new() -> Self {
52        Self {
53            inner: HashMap::new(),
54        }
55    }
56
57    pub fn has<T: ReprRule + ?Sized>(&self) -> bool {
58        self.get::<T>().is_some()
59    }
60
61    pub fn pretty(&self) {
62        eprintln!("{:#?}", self.inner);
63    }
64
65    pub fn get<T: ReprRule + ?Sized>(&self) -> Option<&T::DeclLevel> {
66        self.inner
67            .get(T::NAME)
68            .and_then(|x| x.as_any().downcast_ref())
69    }
70
71    pub fn get_mut<T: ReprRule + ?Sized>(&mut self) -> Option<&mut T::DeclLevel> {
72        self.inner
73            .get_mut(T::NAME)
74            .and_then(|x| x.as_any_mut().downcast_mut())
75    }
76
77    pub fn get_by_rule(&self, rule: &dyn ReprRuleStored) -> Option<&dyn ReprStateStored> {
78        self.inner.get(rule.name()).map(AsRef::as_ref)
79    }
80
81    pub fn has_repr(&self, rule: &dyn ReprRuleStored) -> bool {
82        self.get_by_rule(rule).is_some()
83    }
84
85    pub fn put<T: ReprRule + ?Sized>(&mut self, value: T::DeclLevel) {
86        self.inner.insert(T::NAME, Box::new(value));
87    }
88
89    pub fn iter(&self) -> impl Iterator<Item = (&'static str, &dyn ReprStateStored)> {
90        self.inner.iter().map(|(k, v)| (*k, v.as_ref()))
91    }
92
93    pub fn len(&self) -> usize {
94        self.inner.len()
95    }
96
97    pub fn is_empty(&self) -> bool {
98        self.inner.is_empty()
99    }
100}
101
102impl Serialize for ReprStore {
103    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104    where
105        S: Serializer,
106    {
107        let mut map = serializer.serialize_map(Some(self.inner.len()))?;
108        for (&name, state) in &self.inner {
109            let value = state.serialise().map_err(serde::ser::Error::custom)?;
110            map.serialize_entry(name, &value)?;
111        }
112        map.end()
113    }
114}
115
116impl<'de> Deserialize<'de> for ReprStore {
117    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
118    where
119        D: Deserializer<'de>,
120    {
121        struct ReprStoreVisitor;
122
123        impl<'de> Visitor<'de> for ReprStoreVisitor {
124            type Value = ReprStore;
125
126            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
127                formatter.write_str("a map of repr rule names to their serialized states")
128            }
129
130            fn visit_map<M>(self, mut access: M) -> Result<ReprStore, M::Error>
131            where
132                M: MapAccess<'de>,
133            {
134                let mut inner = HashMap::new();
135
136                while let Some((key, value)) = access.next_entry::<String, serde_json::Value>()? {
137                    let repr = get_repr_by_name(&key).ok_or_else(|| {
138                        serde::de::Error::custom(format!(
139                            "unknown repr rule '{}'; was it registered?",
140                            key
141                        ))
142                    })?;
143                    let state = repr
144                        .deserialize_state(value)
145                        .map_err(serde::de::Error::custom)?;
146                    inner.insert(repr.name(), state);
147                }
148
149                Ok(ReprStore { inner })
150            }
151        }
152
153        deserializer.deserialize_map(ReprStoreVisitor)
154    }
155}