codeviz_common 0.2.2

Flexible code generator for Rust
Documentation
use super::*;

#[derive(Debug, Clone)]
pub enum Element<Var>
where
    Var: VariableFormat,
{
    Push(Statement<Var>),
    Concat(Statement<Var>),
    Literal(String),
    Inner(Vec<Element<Var>>),
    Nested(Box<Element<Var>>),
    Spacing,
}

impl<Var> Element<Var>
where
    Var: VariableFormat,
{
    pub fn format<E>(&self, out: &mut E, extra: &mut Var::Extra) -> Result<()>
    where
        E: ElementFormat,
    {
        match *self {
            Element::Push(ref statement) => {
                out.new_line_unless_empty()?;
                statement.format(out, 0usize, extra)?;
            }
            Element::Concat(ref statement) => {
                statement.format(out, 0usize, extra)?;
            }
            Element::Literal(ref line) => {
                out.new_line_unless_empty()?;
                out.write_str(line)?;
            }
            Element::Inner(ref elements) => {
                for element in elements {
                    element.format(out, extra)?;
                }
            }
            Element::Nested(ref element) => {
                out.new_line_unless_empty()?;

                out.indent();
                element.format(out, extra)?;
                out.unindent();
            }
            Element::Spacing => {
                out.new_line_unless_empty()?;
                out.new_line()?;
            }
        }

        Ok(())
    }
}

impl<'a, T, Var> From<&'a T> for Element<Var>
where
    T: Into<Element<Var>> + Clone,
    Var: VariableFormat,
{
    fn from(value: &'a T) -> Element<Var> {
        value.clone().into()
    }
}

impl<'a, Var> From<&'a str> for Element<Var>
where
    Var: VariableFormat,
{
    fn from(value: &'a str) -> Element<Var> {
        Element::Literal(value.to_owned())
    }
}

impl<Var> From<Elements<Var>> for Element<Var>
where
    Var: VariableFormat,
{
    fn from(value: Elements<Var>) -> Element<Var> {
        Element::Inner(value.elements)
    }
}

impl<Var> From<Vec<String>> for Element<Var>
where
    Var: VariableFormat,
{
    fn from(value: Vec<String>) -> Element<Var> {
        Element::Inner(value.into_iter().map(Element::Literal).collect())
    }
}

impl<Var> ToString for Element<Var>
where
    Var: VariableFormat,
{
    fn to_string(&self) -> String {
        let mut s = String::new();
        let mut extra = Var::Extra::default();
        self.format(&mut ElementFormatter::new(&mut s), &mut extra)
            .unwrap();
        s
    }
}