ephemeris_documents/toml/
layout.rs1use toml_edit::{Item, RawString, Table, TableLike, Value as TomlValue};
4
5use super::decor::prefix_str;
6
7#[derive(Debug)]
9pub struct Siblings<'a>(&'a mut Item);
10
11impl<'a> Siblings<'a> {
12 pub const fn of(container: &'a mut Item) -> Self {
14 Self(container)
15 }
16
17 pub fn append(self, key: &str, node: Item) {
19 match self.0 {
20 Item::Table(table) => Self::append_to_table(table, key, node),
21 Item::Value(TomlValue::InlineTable(table)) => {
22 let last_suffix = table
23 .iter_mut()
24 .last()
25 .and_then(|(_, value)| Self::take_suffix(value));
26 TableLike::insert(table, key, Self::value_of(node, last_suffix));
27 }
28 Item::Value(_) | Item::ArrayOfTables(_) | Item::None => {}
29 }
30 }
31
32 fn append_to_table(table: &mut Table, key: &str, node: Item) {
33 let indent = node.is_value().then(|| Self::indent_of(table)).flatten();
34 table.insert(key, node);
35 if let (Some(indent), Some(mut key)) = (indent, table.key_mut(key)) {
36 key.leaf_decor_mut().set_prefix(indent);
37 }
38 }
39
40 fn indent_of(table: &Table) -> Option<String> {
43 let (name, _) = table.iter().filter(|(_, item)| item.is_value()).last()?;
44 let prefix = prefix_str(table.key(name)?.leaf_decor())?;
45 let indent = prefix.rsplit('\n').next()?;
46 indent
47 .chars()
48 .all(|c| c == ' ' || c == '\t')
49 .then(|| indent.to_owned())
50 }
51
52 fn take_suffix(value: &mut TomlValue) -> Option<RawString> {
55 let suffix = value.decor().suffix()?.clone();
56 value.decor_mut().set_suffix("");
57 Some(suffix)
58 }
59
60 fn value_of(node: Item, suffix: Option<RawString>) -> Item {
61 match (node, suffix) {
62 (Item::Value(mut value), Some(suffix)) => {
63 value.decor_mut().set_suffix(suffix);
64 Item::Value(value)
65 }
66 (node, _) => node,
67 }
68 }
69}