///|
pub fn Document::entries(
self : Document,
section : String,
key : String,
) -> Array[Node] {
self.nodes.filter(n => {
n.kind == Entry &&
same_name(n.section, section, self.dialect) &&
same_name(n.key, key, self.dialect)
})
}
///|
/// Reject policy returns None for ambiguous duplicates. Inspect diagnostics for cause.
pub fn Document::get(
self : Document,
section : String,
key : String,
) -> String? {
let entries = self.entries(section, key)
if entries.is_empty() {
return None
}
match self.dialect.duplicates {
Reject => if entries.length() == 1 { Some(entries[0].value) } else { None }
FirstWins => Some(entries[0].value)
LastWins => Some(entries[entries.length() - 1].value)
}
}
///|
/// Unique explicit section names in source order, including empty sections.
pub fn Document::sections(self : Document) -> Array[String] {
let names : Array[String] = []
for n in self.nodes {
if n.kind == Section &&
!names.any(s => same_name(s, n.section, self.dialect)) {
names.push(n.section)
}
}
names
}
///|
pub fn Document::keys(self : Document, section : String) -> Array[String] {
let names : Array[String] = []
for n in self.nodes {
if n.kind == Entry &&
same_name(n.section, section, self.dialect) &&
!names.any(s => same_name(s, n.key, self.dialect)) {
names.push(n.key)
}
}
names
}