toml_input/
value.rs

1use toml::{map::Map, Value as TomlValue};
2
3use crate::util;
4#[derive(Debug, Clone)]
5#[derive(Default)]
6pub struct BlockValue {
7    pub key: String,
8    pub tag: String,
9    pub value: Option<TomlValue>,
10    pub array_index: Option<usize>,
11}
12
13
14#[derive(Debug, Clone, Default)]
15pub struct PrimValue {
16    pub tag: String,
17    pub raw: Option<TomlValue>,
18}
19
20impl PrimValue {
21    pub fn new(raw: TomlValue) -> Self {
22        PrimValue {
23            raw: Some(raw),
24            ..Default::default()
25        }
26    }
27    pub fn flatten(self) -> BlockValue {
28        let PrimValue { tag, raw } = self;
29        BlockValue {
30            tag,
31            value: raw,
32            ..Default::default()
33        }
34    }
35}
36
37#[derive(Debug, Clone, Default)]
38pub struct ArrayValue {
39    pub values: Vec<Value>,
40}
41
42impl ArrayValue {
43    pub fn into_prim(self) -> PrimValue {
44        let mut raws = Vec::new();
45        for value in self.values {
46            let PrimValue { raw, .. } = value.into_prim();
47            if let Some(raw) = raw {
48                raws.push(raw);
49            }
50        }
51        PrimValue {
52            tag: String::new(),
53            raw: Some(TomlValue::Array(raws)),
54        }
55    }
56
57    pub fn flatten(self) -> Vec<BlockValue> {
58        let ArrayValue { values, .. } = self;
59        let mut blocks = Vec::new();
60        for (i, value) in values.into_iter().enumerate() {
61            let tmp = value.flatten();
62            for mut block in tmp {
63                block.array_index = Some(i);
64                blocks.push(block);
65            }
66        }
67        blocks
68    }
69}
70
71#[derive(Debug, Clone, Default)]
72pub struct TableValue {
73    pub fields: Vec<FieldValue>,
74}
75
76impl TableValue {
77    pub fn into_prim(self) -> PrimValue {
78        let mut map = Map::new();
79        for field in self.fields {
80            for (key, value) in field.into_map() {
81                map.insert(key, value);
82            }
83        }
84        PrimValue {
85            tag: String::new(),
86            raw: Some(TomlValue::Table(map)),
87        }
88    }
89
90    pub fn flatten(self) -> Vec<BlockValue> {
91        let TableValue { fields, .. } = self;
92        let mut values = Vec::new();
93        for field in fields {
94            values.append(&mut field.flatten());
95        }
96        values
97    }
98}
99
100#[derive(Debug, Clone)]
101pub enum Value {
102    Prim(PrimValue),
103    Array(ArrayValue),
104    Table(TableValue),
105}
106
107impl Default for Value {
108    fn default() -> Self {
109        Value::Prim(PrimValue::default())
110    }
111}
112
113impl Value {
114    pub fn new_prim(raw: TomlValue) -> Self {
115        let prim = PrimValue::new(raw);
116        Value::Prim(prim)
117    }
118
119    pub fn into_prim(self) -> PrimValue {
120        match self {
121            Value::Prim(prim) => prim,
122            Value::Array(array) => array.into_prim(),
123            Value::Table(table) => table.into_prim(),
124        }
125    }
126
127    pub fn is_prim(&self) -> bool {
128        matches!(self, Value::Prim(_))
129    }
130
131    pub fn is_array(&self) -> bool {
132        matches!(self, Value::Array(_))
133    }
134
135    pub fn is_table(&self) -> bool {
136        matches!(self, Value::Table(_))
137    }
138
139    pub fn flatten(self) -> Vec<BlockValue> {
140        match self {
141            Value::Prim(prim) => vec![prim.flatten()],
142            Value::Array(array) => array.flatten(),
143            Value::Table(table) => table.flatten(),
144        }
145    }
146}
147
148#[derive(Debug, Clone, Default)]
149pub struct FieldValue {
150    pub ident: String,
151    pub value: Value,
152    pub flat: bool,
153}
154
155impl FieldValue {
156    pub fn into_map(self) -> Map<String, TomlValue> {
157        let FieldValue { ident, value, flat } = self;
158        let PrimValue { raw, .. } = value.into_prim();
159        let mut map = Map::new();
160        if flat {
161            if let Some(TomlValue::Table(map)) = raw {
162                return map;
163            }
164        }
165        if let Some(raw) = raw {
166            map.insert(ident, raw);
167        }
168        map
169    }
170    pub fn flatten(self) -> Vec<BlockValue> {
171        let FieldValue { ident, value, flat } = self;
172        let mut blocks = value.flatten();
173        if !flat {
174            for block in &mut blocks {
175                util::increase_key(&mut block.key, &ident);
176            }
177        }
178        blocks
179    }
180}