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#[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}