libreda_db/
property_storage.rs1use crate::rc_string::RcString;
9use std::borrow::Borrow;
10use std::collections::HashMap;
11use std::convert::TryInto;
12use std::hash::Hash;
13use std::sync::Arc;
14
15#[derive(Debug, Clone)]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21pub enum PropertyValue {
22 String(RcString),
24 Bytes(Vec<u8>),
26 SInt(i32),
28 UInt(u32),
30 Float(f64),
32 }
35
36impl PropertyValue {
37 pub fn get_string(&self) -> Option<RcString> {
39 match self {
40 PropertyValue::String(s) => Some(s.clone()),
41 _ => None,
42 }
43 }
44
45 pub fn get_str(&self) -> Option<&str> {
47 match self {
48 PropertyValue::String(s) => Some(s.as_str()),
49 _ => None,
50 }
51 }
52
53 pub fn get_bytes(&self) -> Option<&Vec<u8>> {
55 match self {
56 PropertyValue::Bytes(s) => Some(s),
57 _ => None,
58 }
59 }
60
61 pub fn get_float(&self) -> Option<f64> {
63 match self {
64 PropertyValue::Float(v) => Some(*v),
65 _ => None,
66 }
67 }
68
69 pub fn get_sint(&self) -> Option<i32> {
71 match self {
72 PropertyValue::SInt(v) => Some(*v),
73 _ => None,
74 }
75 }
76
77 pub fn get_uint(&self) -> Option<u32> {
79 match self {
80 PropertyValue::UInt(v) => Some(*v),
81 _ => None,
82 }
83 }
84
85 }
93
94impl From<String> for PropertyValue {
100 fn from(v: String) -> Self {
101 PropertyValue::String(v.into())
102 }
103}
104
105impl From<Arc<String>> for PropertyValue {
106 fn from(v: Arc<String>) -> Self {
107 PropertyValue::String(v.into())
108 }
109}
110
111impl From<&Arc<String>> for PropertyValue {
112 fn from(v: &Arc<String>) -> Self {
113 PropertyValue::String(v.into())
114 }
115}
116
117impl From<&str> for PropertyValue {
118 fn from(v: &str) -> Self {
119 PropertyValue::String(v.into())
120 }
121}
122
123impl From<Vec<u8>> for PropertyValue {
124 fn from(v: Vec<u8>) -> Self {
125 PropertyValue::Bytes(v)
126 }
127}
128
129impl<'a> TryInto<&'a str> for &'a PropertyValue {
130 type Error = ();
131
132 fn try_into(self) -> Result<&'a str, Self::Error> {
133 if let PropertyValue::String(s) = self {
134 Ok(s.as_str())
135 } else {
136 Err(())
137 }
138 }
139}
140
141impl From<i32> for PropertyValue {
142 fn from(v: i32) -> Self {
143 PropertyValue::SInt(v)
144 }
145}
146
147impl TryInto<i32> for &PropertyValue {
148 type Error = ();
149
150 fn try_into(self) -> Result<i32, Self::Error> {
151 if let PropertyValue::SInt(v) = self {
152 Ok(*v)
153 } else {
154 Err(())
155 }
156 }
157}
158
159impl From<u32> for PropertyValue {
160 fn from(v: u32) -> Self {
161 PropertyValue::UInt(v)
162 }
163}
164
165impl From<f64> for PropertyValue {
166 fn from(v: f64) -> Self {
167 PropertyValue::Float(v)
168 }
169}
170
171#[derive(Debug, Clone)]
179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
180pub struct PropertyStore<K>
181where
182 K: Hash + Eq,
183{
184 content: HashMap<K, PropertyValue>,
185}
186
187impl<K: Hash + Eq> Default for PropertyStore<K> {
188 fn default() -> Self {
189 Self::new()
190 }
191}
192
193impl<K: Hash + Eq> PropertyStore<K> {
194 pub fn new() -> Self {
196 PropertyStore {
197 content: HashMap::new(),
198 }
199 }
200
201 pub fn insert<V: Into<PropertyValue>>(&mut self, key: K, value: V) -> Option<PropertyValue> {
204 self.content.insert(key, value.into())
205 }
206
207 pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&PropertyValue>
209 where
210 K: Borrow<Q>,
211 Q: Eq + Hash,
212 {
213 self.content.get(key)
214 }
215
216 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
218 where
219 K: Borrow<Q>,
220 Q: Eq + Hash,
221 {
222 self.content.contains_key(key)
223 }
224
225 pub fn get_string<Q: ?Sized>(&self, key: &Q) -> Option<&RcString>
228 where
229 K: Borrow<Q>,
230 Q: Eq + Hash,
231 {
232 self.get(key).and_then(|v| {
233 if let PropertyValue::String(s) = v {
234 Some(s)
235 } else {
236 None
237 }
238 })
239 }
240}
241
242pub trait WithProperties {
244 type Key: Hash + Eq;
246
247 fn with_properties<F, R>(&self, f: F) -> R
252 where
253 F: FnOnce(Option<&PropertyStore<Self::Key>>) -> R;
254
255 fn with_properties_mut<F, R>(&self, f: F) -> R
257 where
258 F: FnOnce(&mut PropertyStore<Self::Key>) -> R;
259
260 fn property<Q: ?Sized>(&self, key: &Q) -> Option<PropertyValue>
262 where
263 Self::Key: Borrow<Q>,
264 Q: Eq + Hash,
265 {
266 self.with_properties(|p| p.and_then(|p| p.get(key).cloned()))
267 }
268
269 fn property_str<Q: ?Sized>(&self, key: &Q) -> Option<RcString>
272 where
273 Self::Key: Borrow<Q>,
274 Q: Eq + Hash,
275 {
276 self.with_properties(|p| p.and_then(|p| p.get_string(key).cloned()))
277 }
278
279 fn set_property<V: Into<PropertyValue>>(
282 &self,
283 key: Self::Key,
284 value: V,
285 ) -> Option<PropertyValue> {
286 self.with_properties_mut(|p| p.insert(key, value))
287 }
288}