use super::text;
use super::{Mode, Writer};
use crate::parse::CommentPlacement;
use crate::value::{UclArray, UclObject, UclValue};
impl Writer<'_> {
pub(super) fn config_root(&mut self, value: &UclValue) {
self.comments_before(0);
match value {
UclValue::Object(object) => self.config_entries(object, 0),
UclValue::Array(items) if items.is_empty() => self.out.push_str("[]"),
UclValue::Array(items) => {
self.out.push_str("[\n");
self.config_elements(items, 1);
self.out.push(']');
}
scalar => self.config_scalar(scalar),
}
self.comments_after(0);
}
fn config_entries(&mut self, object: &UclObject, depth: usize) {
for (key, entry) in object.iter() {
for (index, value) in entry.values().enumerate() {
self.enter_key(key, index);
self.config_entry(key, value, depth);
self.leave();
}
}
}
fn config_entry(&mut self, key: &str, value: &UclValue, depth: usize) {
self.indent(depth);
self.comments_before(depth);
self.write_key(key);
match value {
UclValue::Object(object) if object.is_empty() => self.out.push_str(" {}\n"),
UclValue::Object(object) => {
self.out.push_str(" {\n");
self.config_entries(object, depth + 1);
self.indent(depth);
self.out.push_str("}\n");
}
UclValue::Array(items) if items.is_empty() => self.out.push_str(" []\n"),
UclValue::Array(items) => {
self.out.push_str(" [\n");
self.config_elements(items, depth + 1);
self.indent(depth);
self.out.push_str("]\n");
}
scalar => {
self.out.push_str(" = ");
self.config_scalar(scalar);
self.out.push_str(";\n");
}
}
self.comments_after(depth);
}
fn config_elements(&mut self, items: &UclArray, depth: usize) {
for (index, item) in items.iter().enumerate() {
self.enter_index(index);
self.indent(depth);
self.comments_before(depth);
match item {
UclValue::Object(object) if object.is_empty() => self.out.push_str("{}\n"),
UclValue::Object(object) => {
self.out.push_str("{\n");
self.config_entries(object, depth + 1);
self.indent(depth);
self.out.push_str("}\n");
}
UclValue::Array(inner) if inner.is_empty() => self.out.push_str("[]\n"),
UclValue::Array(inner) => {
self.out.push_str("[\n");
self.config_elements(inner, depth + 1);
self.indent(depth);
self.out.push_str("]\n");
}
scalar => {
self.config_scalar(scalar);
self.out.push_str(",\n");
}
}
self.comments_after(depth);
self.leave();
}
}
fn config_scalar(&mut self, value: &UclValue) {
if self.mode == Mode::RoundTrip {
self.exact_scalar(value, true);
return;
}
match value {
UclValue::String(s) => {
let (single_quoted, multiline) = self
.facts()
.map_or((false, false), |f| (f.single_quoted, f.multiline));
text::write_config_string(&mut self.out, s, single_quoted, multiline);
}
other => self.scalar(other),
}
}
fn comments_before(&mut self, depth: usize) {
for text in self.comments(CommentPlacement::Before) {
self.out.push_str(text);
self.out.push('\n');
self.indent(depth);
}
}
fn comments_after(&mut self, depth: usize) {
for (i, text) in self
.comments(CommentPlacement::After)
.into_iter()
.enumerate()
{
if i > 0 {
self.indent(depth);
}
self.out.push_str(text);
self.out.push('\n');
}
}
}