use super::insert::Additive;
use super::{HashData, HashElement, Yaml};
use super::{Pretty, YamlInsert};
use crate::YamlPath;
use std::fmt::Write;
#[derive(Debug, Clone, PartialEq)]
pub enum DocumentData {
Comment(String),
Yaml(Yaml),
}
impl YamlInsert for DocumentData {
fn edit_hash_structure<F>(&mut self, path: &YamlPath, f: &F) -> usize
where
F: Fn(&mut Vec<HashData>, String, Option<usize>) -> usize,
{
match self {
DocumentData::Yaml(y) => y.edit_hash_structure(path, f),
_ => 0,
}
}
fn for_hash<F, R, A: Additive>(&mut self, path: &YamlPath, f: &F, r: &R) -> A
where
F: Fn(&mut HashElement) -> A,
R: Fn(&mut Yaml) -> A,
{
match self {
DocumentData::Yaml(y) => y.for_hash(path, f, r),
_ => A::zero(),
}
}
}
impl Pretty for DocumentData {
fn pretty_with_options(self, in_inline: bool, _child_of_array: bool) -> Self {
match self {
DocumentData::Comment(c) => DocumentData::Comment(c),
DocumentData::Yaml(c) => DocumentData::Yaml(c.pretty_with_options(in_inline, false)),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Document {
pub leading_comments: Vec<String>,
pub items: Vec<DocumentData>,
}
impl YamlInsert for Document {
fn edit_hash_structure<F>(&mut self, path: &YamlPath, f: &F) -> usize
where
F: Fn(&mut Vec<HashData>, String, Option<usize>) -> usize,
{
let mut count = 0;
for item in self.items.iter_mut() {
count += item.edit_hash_structure(path, f);
}
count
}
fn for_hash<F, R, A: Additive>(&mut self, path: &YamlPath, f: &F, r: &R) -> A
where
F: Fn(&mut HashElement) -> A,
R: Fn(&mut Yaml) -> A,
{
let mut count = A::zero();
for item in self.items.iter_mut() {
count = count + item.for_hash(path, f, r);
}
count
}
}
impl Document {
pub fn format(&self) -> Result<String, std::fmt::Error> {
let mut s = String::new();
for comment in self.leading_comments.iter() {
writeln!(&mut s, "#{}", comment)?;
}
write!(s, "---")?;
for item in self.items.iter() {
match item {
DocumentData::Comment(c) => write!(&mut s, "\n#{}", c),
DocumentData::Yaml(y) => y.format(&mut s, 0, None),
}?;
}
Ok(s)
}
}
impl Pretty for Document {
fn pretty_with_options(self, _in_inline: bool, _child_of_array: bool) -> Self {
Self {
leading_comments: self.leading_comments,
items: self.items.pretty_with_options(false, false),
}
}
}