use crate::namelist::NamelistGroup;
use crate::namelist::{Array, Item, Map};
pub(crate) struct NamelistFormatter<'a> {
key_prefix: Vec<&'a str>,
}
impl<'a> NamelistFormatter<'a> {
pub(crate) fn new() -> Self {
NamelistFormatter {
key_prefix: Vec::new(),
}
}
pub(crate) fn fmt_namelist(
&mut self,
namelist: &'a NamelistGroup,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
writeln!(formatter, " &{}", namelist.group_name)?;
self.fmt_map(&namelist.items, formatter)?;
write!(formatter, " /")
}
fn fmt_key_prefix(&mut self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for p in &self.key_prefix {
write!(formatter, "{p}%")?;
}
Ok(())
}
fn fmt_map(
&mut self,
kv: &'a Map<String, Item>,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
for (key, item) in kv {
match item {
Item::Literal(lit) => {
write!(formatter, " ")?;
self.fmt_key_prefix(formatter)?;
writeln!(formatter, "{key} = {lit},")?;
}
Item::Derived(d) => {
self.key_prefix.push(key);
self.fmt_map(d, formatter)?;
self.key_prefix.pop();
}
Item::Array(array) => {
write!(formatter, " ")?;
self.fmt_key_prefix(formatter)?;
write!(formatter, "{key} = ")?;
self.fmt_array(array, formatter)?;
write!(formatter, "\n")?;
}
}
}
Ok(())
}
fn fmt_array(
&mut self,
array: &'a Array,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
match array {
Array::RepeatedConstant(r, lit) => {
self.fmt_key_prefix(formatter)?;
writeln!(formatter, " = {r}*{lit}")?;
}
Array::List(list) => {
for (r, lit) in list {
if *r > 1 {
write!(formatter, " {r}*{lit},")?;
} else {
write!(formatter, " {lit},")?;
}
}
}
Array::Indexed(_map) => {
unimplemented!()
}
}
Ok(())
}
}