partiql_common/
metadata.rs

1use indexmap::map::Entry;
2use indexmap::IndexMap;
3use rust_decimal::Decimal;
4use std::borrow::Borrow;
5use std::fmt::Result;
6use std::fmt::{Display, Formatter};
7use std::hash::Hash;
8
9/// Provides a mean to store meta-data for PartiQL objects.
10///
11/// # Examples
12/// ```
13/// use partiql_common::metadata::{PartiqlMetadata, PartiqlMetaValue};
14///
15/// let foo_val = PartiqlMetaValue::String("foo".to_string());
16/// let i64_val = PartiqlMetaValue::Int64(2);///
17/// let expected_vec_val = vec![foo_val, i64_val];
18///
19/// let expected_bool_val = true;///
20/// let expected_int_val = 2;///
21/// let expected_float_val = 2.5;///
22/// let expected_str_val = "foo";///
23///
24/// let mut expected_map = PartiqlMetadata::new();///
25/// expected_map.insert("bool value", expected_bool_val.into());///
26/// expected_map.insert("integer value", expected_int_val.into());///
27///
28/// let mut metas = PartiqlMetadata::new();///
29/// metas.insert("vec value", expected_vec_val.clone().into());
30/// metas.insert("bool value", expected_bool_val.into());///
31/// metas.insert("integer value", expected_int_val.into());///
32/// metas.insert("float value", expected_float_val.into());///
33/// metas.insert("string value", expected_str_val.into());///
34/// metas.insert("map value", expected_map.clone().into());///
35///
36/// let vec_val = metas.vec_value("vec value").expect("vec meta value");///
37/// let bool_val = metas.bool_value("bool value").expect("bool meta value");///
38/// let int_val = metas.i32_value("integer value").expect("i32 meta value");///
39/// let float_val = metas.f64_value("float value").expect("f64 meta value");///
40/// let string_val = metas.string_value("string value").expect("string meta value");///
41/// let map_val = metas.map_value("map value").expect("map meta value");///
42///
43/// assert_eq!(vec_val, expected_vec_val.clone());///
44/// assert_eq!(bool_val, expected_bool_val.clone());///
45/// assert_eq!(int_val, expected_int_val.clone());///
46/// assert_eq!(float_val, expected_float_val.clone());///
47/// assert_eq!(string_val, expected_str_val);///
48/// assert_eq!(map_val, expected_map.clone());
49/// ```
50#[derive(Debug, Clone, PartialEq)]
51pub struct PartiqlMetadata<T>
52where
53    T: Eq + Clone + Hash + Borrow<str>,
54{
55    inner: IndexMap<T, PartiqlMetaValue<T>>,
56}
57
58#[allow(dead_code)]
59impl<T> PartiqlMetadata<T>
60where
61    T: Eq + Clone + Hash + Borrow<str>,
62{
63    pub fn new() -> Self {
64        Self {
65            inner: IndexMap::new(),
66        }
67    }
68
69    pub fn insert(&mut self, key: T, value: PartiqlMetaValue<T>) {
70        self.inner.insert(key, value);
71    }
72
73    pub fn get(&self, key: &T) -> Option<&PartiqlMetaValue<T>> {
74        self.inner.get(key)
75    }
76
77    pub fn get_mut(&mut self, key: &T) -> Option<&mut PartiqlMetaValue<T>> {
78        self.inner.get_mut(key)
79    }
80
81    pub fn contains_key(&self, key: &T) -> bool {
82        self.inner.contains_key(key)
83    }
84
85    pub fn keys(&self) -> impl Iterator<Item = &T> {
86        self.inner.keys()
87    }
88
89    pub fn values(&self) -> impl Iterator<Item = &PartiqlMetaValue<T>> {
90        self.inner.values()
91    }
92
93    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut PartiqlMetaValue<T>> {
94        self.inner.values_mut()
95    }
96
97    pub fn entry(&mut self, key: T) -> Entry<'_, T, PartiqlMetaValue<T>> {
98        self.inner.entry(key)
99    }
100
101    pub fn clear(&mut self) {
102        self.inner.clear();
103    }
104
105    pub fn remove(&mut self, key: &T) -> Option<PartiqlMetaValue<T>> {
106        self.inner.swap_remove(key)
107    }
108
109    pub fn len(&self) -> usize {
110        self.inner.len()
111    }
112
113    pub fn is_empty(&self) -> bool {
114        self.inner.is_empty()
115    }
116
117    pub fn iter(&self) -> impl Iterator<Item = (&T, &PartiqlMetaValue<T>)> {
118        self.inner.iter()
119    }
120
121    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&T, &mut PartiqlMetaValue<T>)> {
122        self.inner.iter_mut()
123    }
124
125    pub fn vec_value(&self, key: &str) -> Option<Vec<PartiqlMetaValue<T>>> {
126        let value = self.inner.get(key);
127        if let Some(PartiqlMetaValue::Array(v)) = value {
128            Some(v.clone())
129        } else {
130            None
131        }
132    }
133
134    pub fn bool_value(&self, key: &str) -> Option<bool> {
135        let value = self.inner.get(key);
136        if let Some(PartiqlMetaValue::Bool(v)) = value {
137            Some(*v)
138        } else {
139            None
140        }
141    }
142
143    pub fn f32_value(&self, key: &str) -> Option<f32> {
144        let value = self.inner.get(key);
145        if let Some(PartiqlMetaValue::Float32(v)) = value {
146            Some(*v)
147        } else {
148            None
149        }
150    }
151
152    pub fn f64_value(&self, key: &str) -> Option<f64> {
153        let value = self.inner.get(key);
154        if let Some(PartiqlMetaValue::Float64(v)) = value {
155            Some(*v)
156        } else {
157            None
158        }
159    }
160
161    pub fn decimal_value(&self, key: &str) -> Option<Decimal> {
162        let value = self.inner.get(key);
163        if let Some(PartiqlMetaValue::Decimal(v)) = value {
164            Some(*v)
165        } else {
166            None
167        }
168    }
169
170    pub fn i32_value(&self, key: &str) -> Option<i32> {
171        let value = self.inner.get(key);
172        if let Some(PartiqlMetaValue::Int32(v)) = value {
173            Some(*v)
174        } else {
175            None
176        }
177    }
178
179    pub fn i64_value(&self, key: &str) -> Option<i64> {
180        let value = self.inner.get(key);
181        if let Some(PartiqlMetaValue::Int64(v)) = value {
182            Some(*v)
183        } else {
184            None
185        }
186    }
187
188    pub fn map_value(&self, key: &str) -> Option<PartiqlMetadata<T>> {
189        let value = self.inner.get(key);
190        if let Some(PartiqlMetaValue::Map(v)) = value {
191            Some(v.clone())
192        } else {
193            None
194        }
195    }
196
197    pub fn string_value(&self, key: &str) -> Option<String> {
198        let value = self.inner.get(key);
199        if let Some(PartiqlMetaValue::String(v)) = value {
200            Some(v.clone())
201        } else {
202            None
203        }
204    }
205}
206
207impl<T> Default for PartiqlMetadata<T>
208where
209    T: Eq + Clone + Hash + Borrow<str>,
210{
211    fn default() -> Self {
212        Self {
213            inner: IndexMap::new(),
214        }
215    }
216}
217
218impl<T> FromIterator<(T, PartiqlMetaValue<T>)> for PartiqlMetadata<T>
219where
220    T: Eq + Clone + Hash + Borrow<str>,
221{
222    fn from_iter<I: IntoIterator<Item = (T, PartiqlMetaValue<T>)>>(iter: I) -> Self {
223        let inner = iter.into_iter().collect();
224        Self { inner }
225    }
226}
227
228impl<T> IntoIterator for PartiqlMetadata<T>
229where
230    T: Eq + Clone + Hash + Borrow<str>,
231{
232    type Item = (T, PartiqlMetaValue<T>);
233    type IntoIter = indexmap::map::IntoIter<T, PartiqlMetaValue<T>>;
234
235    fn into_iter(self) -> Self::IntoIter {
236        self.inner.into_iter()
237    }
238}
239
240#[derive(Clone, Debug, PartialEq)]
241#[allow(dead_code)]
242pub enum PartiqlMetaValue<T>
243where
244    T: Eq + Clone + Hash + Borrow<str>,
245{
246    Array(Vec<PartiqlMetaValue<T>>),
247    Bool(bool),
248    Float32(f32),
249    Float64(f64),
250    Decimal(Decimal),
251    Int32(i32),
252    Int64(i64),
253    Map(PartiqlMetadata<T>),
254    String(String),
255}
256
257impl<T> From<bool> for PartiqlMetaValue<T>
258where
259    T: Eq + Clone + Hash + Borrow<str>,
260{
261    fn from(value: bool) -> Self {
262        PartiqlMetaValue::Bool(value)
263    }
264}
265
266impl<T> From<i32> for PartiqlMetaValue<T>
267where
268    T: Eq + Clone + Hash + Borrow<str>,
269{
270    fn from(value: i32) -> Self {
271        PartiqlMetaValue::Int32(value)
272    }
273}
274impl<T> From<i64> for PartiqlMetaValue<T>
275where
276    T: Eq + Clone + Hash + Borrow<str>,
277{
278    fn from(value: i64) -> Self {
279        PartiqlMetaValue::Int64(value)
280    }
281}
282
283impl<T> From<f64> for PartiqlMetaValue<T>
284where
285    T: Eq + Clone + Hash + Borrow<str>,
286{
287    fn from(value: f64) -> Self {
288        PartiqlMetaValue::Float64(value)
289    }
290}
291
292impl<T> From<String> for PartiqlMetaValue<T>
293where
294    T: Eq + Clone + Hash + Borrow<str>,
295{
296    fn from(value: String) -> Self {
297        PartiqlMetaValue::String(value)
298    }
299}
300impl<T> From<&'static str> for PartiqlMetaValue<T>
301where
302    T: Eq + Clone + Hash + Borrow<str>,
303{
304    fn from(value: &'static str) -> Self {
305        PartiqlMetaValue::String(value.to_owned())
306    }
307}
308
309impl<T> From<Vec<PartiqlMetaValue<T>>> for PartiqlMetaValue<T>
310where
311    T: Eq + Clone + Hash + Borrow<str>,
312{
313    fn from(value: Vec<PartiqlMetaValue<T>>) -> Self {
314        PartiqlMetaValue::Array(value)
315    }
316}
317
318impl<T> From<&[PartiqlMetaValue<T>]> for PartiqlMetaValue<T>
319where
320    T: Eq + Clone + Hash + Borrow<str>,
321{
322    fn from(slice: &[PartiqlMetaValue<T>]) -> Self {
323        PartiqlMetaValue::Array(slice.to_vec())
324    }
325}
326
327impl<T> From<PartiqlMetadata<T>> for PartiqlMetaValue<T>
328where
329    T: Eq + Clone + Hash + Borrow<str>,
330{
331    fn from(value: PartiqlMetadata<T>) -> Self {
332        PartiqlMetaValue::Map(value)
333    }
334}
335
336impl<T> Display for PartiqlMetaValue<T>
337where
338    T: Eq + Hash + Display + Clone + Borrow<str>,
339{
340    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
341        match self {
342            PartiqlMetaValue::Array(arr) => {
343                write!(f, "[")?;
344                for (idx, item) in arr.iter().enumerate() {
345                    if idx > 0 {
346                        write!(f, ", ")?;
347                    }
348                    write!(f, "{item}")?;
349                }
350                write!(f, "]")
351            }
352            PartiqlMetaValue::Bool(v) => write!(f, "{v}"),
353            PartiqlMetaValue::Decimal(v) => write!(f, "{v}"),
354            PartiqlMetaValue::Float64(v) => write!(f, "{v}"),
355            PartiqlMetaValue::Float32(v) => write!(f, "{v}"),
356            PartiqlMetaValue::Int32(v) => write!(f, "{v}"),
357            PartiqlMetaValue::Int64(v) => write!(f, "{v}"),
358            PartiqlMetaValue::Map(map) => {
359                write!(f, "{{")?;
360                for (t, v) in map.iter() {
361                    write!(f, "{t}: {v} , ")?;
362                }
363                write!(f, "}}")
364            }
365            PartiqlMetaValue::String(v) => write!(f, "{v}"),
366        }
367    }
368}
369
370#[cfg(test)]
371mod tests {
372    use crate::metadata::{PartiqlMetaValue, PartiqlMetadata};
373
374    #[test]
375    fn test_metadata() {
376        let foo_val = PartiqlMetaValue::String("foo".to_string());
377        let i64_val = PartiqlMetaValue::Int64(2);
378
379        let expected_vec_val = vec![foo_val, i64_val];
380        let expected_bool_val = true;
381        let expected_int_val = 2;
382        let expected_float_val = 2.5;
383        let expected_str_val = "foo";
384
385        let mut expected_map = PartiqlMetadata::new();
386        expected_map.insert("bool value", expected_bool_val.into());
387        expected_map.insert("integer value", expected_int_val.into());
388
389        let mut metas = PartiqlMetadata::new();
390        metas.insert("vec value", expected_vec_val.clone().into());
391        metas.insert("bool value", expected_bool_val.into());
392        metas.insert("integer value", expected_int_val.into());
393        metas.insert("float value", expected_float_val.into());
394        metas.insert("string value", expected_str_val.into());
395        metas.insert("map value", expected_map.clone().into());
396
397        let vec_val = metas.vec_value("vec value").expect("vec meta value");
398        let bool_val = metas.bool_value("bool value").expect("bool meta value");
399        let int_val = metas.i32_value("integer value").expect("i32 meta value");
400        let float_val = metas.f64_value("float value").expect("f64 meta value");
401        let string_val = metas
402            .string_value("string value")
403            .expect("string meta value");
404        let map_val = metas.map_value("map value").expect("map meta value");
405
406        assert_eq!(vec_val, expected_vec_val.clone());
407        assert_eq!(bool_val, expected_bool_val.clone());
408        assert_eq!(int_val, expected_int_val.clone());
409        assert_eq!(float_val, expected_float_val.clone());
410        assert_eq!(string_val, expected_str_val);
411        assert_eq!(map_val, expected_map.clone());
412    }
413}