conjure_cp_core/representation/
store.rs1use 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}