ligen_parser/parser/config/
group.rs1use std::collections::HashMap;
2
3use ligen_ir::{Literal, Path};
4
5use crate::prelude::*;
6
7#[derive(Debug, Serialize, Deserialize, Clone)]
8#[serde(untagged)]
9pub enum Value {
10 Literal(Literal),
11 Group(Group)
12}
13
14#[derive(Debug, Default, Serialize, Deserialize, Clone)]
15pub struct Group {
16 #[serde(flatten)]
17 map: HashMap<String, Value>
18}
19
20impl Group {
21 pub fn iter(&self) -> impl Iterator<Item = (Path, Literal)> {
22 self.map
23 .clone()
24 .into_iter()
25 .flat_map(|(key, value)| {
26 match value {
27 Value::Literal(literal) => {
28 vec![(Path::from(key), literal)]
29 },
30 Value::Group(group) => {
31 group
32 .iter()
33 .map(|(path, literal)| {
34 let mut path = path.clone();
35 path.push_front(key.clone());
36 (path, literal.clone())
37 })
38 .collect()
39 }
40 }
41 })
42 }
43}
44
45impl Group {
46 pub fn set<P: Into<Path>, L: Into<Literal>>(&mut self, path: P, value: L) {
48 let mut path = path.into();
49 if let Some(word) = path.pop_front() {
50 if path.is_empty() {
51 self.map.insert(word.identifier.name, Value::Literal(value.into()));
52 } else {
53 let group = self.map
54 .entry(word.identifier.name)
55 .or_insert_with(|| Value::Group(Group::default()));
56 if let Value::Group(group) = group {
57 group.set(path, value);
58 }
59 }
60 }
61 }
62
63 pub fn get<P: Into<Path>>(&self, path: P) -> Option<&Literal> {
65 let mut path = path.into();
66 if let Some(word) = path.pop_front() {
67 match self
68 .map
69 .get(&word.identifier.name) {
70 Some(Value::Literal(literal)) => {
71 if path.is_empty() {
72 Some(literal)
73 } else {
74 None
75 }
76 },
77 Some(Value::Group(group)) => group.get(path),
78 None => None
79 }
80 } else {
81 None
82 }
83 }
84}