nml/
formatter.rs

1use crate::namelist::NamelistGroup;
2use crate::namelist::{Array, Item, Map};
3
4pub(crate) struct NamelistFormatter<'a> {
5    key_prefix: Vec<&'a str>,
6}
7
8impl<'a> NamelistFormatter<'a> {
9    pub(crate) fn new() -> Self {
10        NamelistFormatter {
11            key_prefix: Vec::new(),
12        }
13    }
14    pub(crate) fn fmt_namelist(
15        &mut self,
16        namelist: &'a NamelistGroup,
17        formatter: &mut std::fmt::Formatter<'_>,
18    ) -> std::fmt::Result {
19        writeln!(formatter, " &{}", namelist.group_name)?;
20        self.fmt_map(&namelist.items, formatter)?;
21        write!(formatter, " /")
22    }
23    fn fmt_key_prefix(&mut self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        for p in &self.key_prefix {
25            write!(formatter, "{p}%")?;
26        }
27        Ok(())
28    }
29    fn fmt_map(
30        &mut self,
31        kv: &'a Map<String, Item>,
32        formatter: &mut std::fmt::Formatter<'_>,
33    ) -> std::fmt::Result {
34        for (key, item) in kv {
35            match item {
36                Item::Literal(lit) => {
37                    write!(formatter, "  ")?;
38                    self.fmt_key_prefix(formatter)?;
39                    writeln!(formatter, "{key} = {lit},")?;
40                }
41                Item::Derived(d) => {
42                    self.key_prefix.push(key);
43                    self.fmt_map(d, formatter)?;
44                    self.key_prefix.pop();
45                }
46                Item::Array(array) => {
47                    write!(formatter, "  ")?;
48                    self.fmt_key_prefix(formatter)?;
49                    write!(formatter, "{key} = ")?;
50                    self.fmt_array(array, formatter)?;
51                    write!(formatter, "\n")?;
52                }
53            }
54        }
55        Ok(())
56    }
57
58    fn fmt_array(
59        &mut self,
60        array: &'a Array,
61        formatter: &mut std::fmt::Formatter<'_>,
62    ) -> std::fmt::Result {
63        match array {
64            Array::RepeatedConstant(r, lit) => {
65                self.fmt_key_prefix(formatter)?;
66                writeln!(formatter, " = {r}*{lit}")?;
67            }
68            Array::List(list) => {
69                for (r, lit) in list {
70                    if *r > 1 {
71                        write!(formatter, " {r}*{lit},")?;
72                    } else {
73                        write!(formatter, " {lit},")?;
74                    }
75                }
76            }
77            Array::Indexed(_map) => {
78                unimplemented!()
79            }
80        }
81
82        Ok(())
83    }
84}