use crate::Value; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct Record { pub cols: Vec, pub vals: Vec, } impl Record { pub fn new() -> Self { Self::default() } pub fn with_capacity(capacity: usize) -> Self { Self { cols: Vec::with_capacity(capacity), vals: Vec::with_capacity(capacity), } } pub fn iter(&self) -> Iter { self.into_iter() } pub fn iter_mut(&mut self) -> IterMut { self.into_iter() } pub fn is_empty(&self) -> bool { self.cols.is_empty() || self.vals.is_empty() } pub fn len(&self) -> usize { usize::min(self.cols.len(), self.vals.len()) } pub fn push(&mut self, col: impl Into, val: Value) { self.cols.push(col.into()); self.vals.push(val); } } impl FromIterator<(String, Value)> for Record { fn from_iter>(iter: T) -> Self { let (cols, vals) = iter.into_iter().unzip(); Self { cols, vals } } } pub type IntoIter = std::iter::Zip, std::vec::IntoIter>; impl IntoIterator for Record { type Item = (String, Value); type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { self.cols.into_iter().zip(self.vals) } } pub type Iter<'a> = std::iter::Zip, std::slice::Iter<'a, Value>>; impl<'a> IntoIterator for &'a Record { type Item = (&'a String, &'a Value); type IntoIter = Iter<'a>; fn into_iter(self) -> Self::IntoIter { self.cols.iter().zip(&self.vals) } } pub type IterMut<'a> = std::iter::Zip, std::slice::IterMut<'a, Value>>; impl<'a> IntoIterator for &'a mut Record { type Item = (&'a String, &'a mut Value); type IntoIter = IterMut<'a>; fn into_iter(self) -> Self::IntoIter { self.cols.iter().zip(&mut self.vals) } } #[macro_export] macro_rules! record { {$($col:expr => $val:expr),+ $(,)?} => { $crate::Record { cols: vec![$($col.into(),)+], vals: vec![$($val,)+] } }; {} => { $crate::Record::new() }; }