toasty_core/stmt/
sparse_record.rs1use super::{PathFieldSet, Type, Value, ValueRecord};
2use std::hash::Hash;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct SparseRecord {
8 pub fields: PathFieldSet,
10
11 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}