toasty_core/stmt/
sparse_record.rs

1use super::{PathFieldSet, Type, Value, ValueRecord};
2use std::hash::Hash;
3
4/// A typed record, indicating the record represents a specific model (or a
5/// subset of its fields).
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct SparseRecord {
8    /// Fields that are present
9    pub fields: PathFieldSet,
10
11    /// Values
12    pub values: Vec<Value>,
13}
14
15impl Value {
16    pub fn empty_sparse_record() -> Self {
17        SparseRecord {
18            fields: PathFieldSet::new(),
19            values: vec![],
20        }
21        .into()
22    }
23
24    pub fn sparse_record(fields: PathFieldSet, record: ValueRecord) -> Self {
25        let mut values = vec![];
26
27        for (index, value) in fields.iter().zip(record.fields.into_iter()) {
28            while index >= values.len() {
29                values.push(Value::Null);
30            }
31
32            values[index] = value;
33        }
34
35        SparseRecord { fields, values }.into()
36    }
37
38    pub fn into_sparse_record(self) -> SparseRecord {
39        match self {
40            Self::SparseRecord(value) => value,
41            _ => todo!(),
42        }
43    }
44}
45
46impl Type {
47    pub fn sparse_record(fields: impl Into<PathFieldSet>) -> Self {
48        Self::SparseRecord(fields.into())
49    }
50
51    pub fn empty_sparse_record() -> Self {
52        Self::SparseRecord(PathFieldSet::default())
53    }
54}
55
56impl IntoIterator for SparseRecord {
57    type Item = (usize, Value);
58
59    type IntoIter = Box<dyn Iterator<Item = (usize, Value)>>;
60
61    fn into_iter(self) -> Self::IntoIter {
62        Box::new(
63            self.values
64                .into_iter()
65                .enumerate()
66                .filter_map(move |(i, value)| {
67                    if self.fields.contains(i) {
68                        Some((i, value))
69                    } else {
70                        None
71                    }
72                }),
73        )
74    }
75}
76
77impl From<SparseRecord> for Value {
78    fn from(value: SparseRecord) -> Self {
79        Self::SparseRecord(value)
80    }
81}