ansiconst 0.2.1

Library for declaring nestable ANSI styles in const context
Documentation
use super::{AnsiNode, StyledString};
use super::super::StyledDisplay;
use std::fmt;

pub(super) struct StyledStringDisplay<'a> {
    remainder: &'a str,
    stack: Vec<AnsiNode>,
}

impl StyledStringDisplay<'_> {
    pub(super) fn fmt_styled_string(f: &mut fmt::Formatter<'_>, styled_string: &StyledString) -> fmt::Result {
        let remainder = styled_string.template.as_str();
        let mut stack: Vec<AnsiNode> = Vec::with_capacity(styled_string.max_depth as usize + 1);
        stack.push(AnsiNode { ansi: StyledDisplay::ansi(), number_of_inner_ansis: 1 });

        let mut display = StyledStringDisplay { remainder, stack };
        for ansi_node in &styled_string.ansi_nodes {
            display.fmt_node(f, ansi_node)?;
        }
        Ok(())
    }

    fn fmt_node(&mut self, f: &mut fmt::Formatter<'_>, ansi_node: &AnsiNode) -> fmt::Result {
        self.fmt_ansi_begin(f, ansi_node)?;
        self.fmt_content(f)?;
        while self.is_ansi_end() {
            self.fmt_ansi_end(f)?;
            self.fmt_content(f)?;
        }
        Ok(())
    }

    fn fmt_ansi_begin(&mut self, f: &mut fmt::Formatter<'_>, ansi_node: &AnsiNode) -> fmt::Result {
        let old_ansi_node = self.stack.last_mut().unwrap();
        old_ansi_node.number_of_inner_ansis -= 1;
        let old_ansi = old_ansi_node.ansi;
        let new_ansi = old_ansi.then(ansi_node.ansi);
        let old_to_new = old_ansi.transition(new_ansi);
        self.stack.push(AnsiNode { ansi: new_ansi.only(), number_of_inner_ansis: ansi_node.number_of_inner_ansis });
        old_to_new.fmt_no_alternate(f)
    }

    fn fmt_content(&mut self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.remainder.len() > 0 {
            if let Some((prefix, remainder)) = self.remainder.split_once(AnsiNode::PLACEHOLDER) {
                self.remainder = remainder;
                f.write_str(prefix)?;
            } else {
                f.write_str(self.remainder)?;
                self.remainder = "";
            }
        }
        Ok(())
    }

    #[inline]
    fn is_ansi_end(&self) -> bool {
        self.stack.len() > 1
        && self.stack.last().unwrap().number_of_inner_ansis == 0
    }

    fn fmt_ansi_end(&mut self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let new_ansi = self.stack.pop().unwrap().ansi;
        let old_ansi = self.stack.last().unwrap().ansi;
        let new_to_old = new_ansi.transition(old_ansi);
        new_to_old.fmt_no_alternate(f)
    }
}