Skip to main content

miniconf_parser/
ast.rs

1use std::collections::BTreeMap;
2
3use serde::Serialize;
4
5/// Parsed MiniConf document consisting of named sections.
6#[derive(Debug, Clone, PartialEq, Serialize)]
7pub struct Document {
8    sections: BTreeMap<String, Section>,
9}
10
11impl Document {
12    /// Creates an empty [`Document`].
13    pub fn new() -> Self {
14        Self {
15            sections: BTreeMap::new(),
16        }
17    }
18
19    /// Returns a section by name, creating it when absent.
20    pub(crate) fn ensure_section_mut(&mut self, name: &str) -> &mut Section {
21        self.sections
22            .entry(name.to_string())
23            .or_insert_with(|| Section::new(name))
24    }
25
26    /// Returns an immutable view of a section, if present.
27    pub fn section(&self, name: &str) -> Option<&Section> {
28        self.sections.get(name)
29    }
30
31    /// Returns an iterator over all sections, ordered by name.
32    pub fn sections(&self) -> impl Iterator<Item = (&String, &Section)> + '_ {
33        self.sections.iter()
34    }
35}
36
37impl Default for Document {
38    fn default() -> Self {
39        Self::new()
40    }
41}
42
43/// A section groups related key/value entries.
44#[derive(Debug, Clone, PartialEq, Serialize)]
45pub struct Section {
46    /// Section identifier as it appeared in the file.
47    pub name: String,
48    /// Key/value entries in declaration order.
49    pub entries: Vec<Entry>,
50}
51
52impl Section {
53    /// Creates a section with no entries.
54    pub fn new(name: &str) -> Self {
55        Self {
56            name: name.to_string(),
57            entries: Vec::new(),
58        }
59    }
60}
61
62/// Single key/value assignment inside a section.
63#[derive(Debug, Clone, PartialEq, Serialize)]
64pub struct Entry {
65    /// Logical key.
66    pub key: String,
67    /// Parsed value.
68    pub value: Value,
69    /// 1-based line number, useful for diagnostics.
70    pub line: usize,
71}
72
73impl Entry {
74    /// Convenience constructor for tests and parser.
75    pub fn new(key: impl Into<String>, value: Value, line: usize) -> Self {
76        Self {
77            key: key.into(),
78            value,
79            line,
80        }
81    }
82}
83
84/// Supported MiniConf values.
85#[derive(Debug, Clone, PartialEq, Serialize)]
86pub enum Value {
87    /// Quoted or bare string data.
88    String(String),
89    /// Integer or floating-point number.
90    Number(f64),
91    /// Boolean (`true`, `false`, `yes`, `no`).
92    Bool(bool),
93    /// Ordered list of nested values.
94    Array(Vec<Value>),
95}
96
97impl Value {
98    /// Returns the string representation when the value is textual.
99    pub fn as_str(&self) -> Option<&str> {
100        match self {
101            Self::String(s) => Some(s),
102            _ => None,
103        }
104    }
105}