yaml-subset 0.1.19

A subset of yaml used in rumbas
Documentation
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),
        }
    }
}