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