logparse 0.3.0

parse arbitrary messages containing rust-like debug output to syntax highlight them
Documentation
use super::ast::*;
use std::fmt::{self, Display};

impl Display for Separator {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Separator::Eq => write!(f, "="),
            Separator::Colon => write!(f, ":"),
            Separator::DoubleColon => write!(f, "::"),
        }
    }
}

impl Display for QuoteType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            QuoteType::Single => write!(f, "\'"),
            QuoteType::Double => write!(f, "\""),
            QuoteType::Backtick => write!(f, "`"),
        }
    }
}

impl Delimiter {
    fn fmt_start(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Delimiter::Paren => write!(f, "("),
            Delimiter::Bracket => write!(f, "["),
            Delimiter::Brace => write!(f, "{{"),
            Delimiter::Angle => write!(f, "<"),
        }
    }

    fn fmt_end(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Delimiter::Paren => write!(f, ")"),
            Delimiter::Bracket => write!(f, "]"),
            Delimiter::Brace => write!(f, "}}"),
            Delimiter::Angle => write!(f, ">"),
        }
    }
}

impl<'a> Display for AnyString<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.prefix)?;
        for _ in 0..self.num_hashtags {
            write!(f, "#")?;
        }
        write!(f, "{}", self.ty)?;
        write!(f, "{}", self.contents)?;
        write!(f, "{}", self.ty)?;

        for _ in 0..self.num_hashtags {
            write!(f, "#")?;
        }
        write!(f, "{}", self.suffix)
    }
}

impl<'a> Display for Space<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl Display for PathSep {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            PathSep::Slash => write!(f, "/"),
            PathSep::Backslash => write!(f, "\\"),
            PathSep::None => Ok(()),
        }
    }
}

impl<'a> Display for PathSegment<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.leading_separator)?;
        write!(f, "{}", self.segment)
    }
}

impl<'a> Display for FileLocation<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, ":{}", self.line)?;
        if let Some(offset) = &self.offset {
            write!(f, ":{offset}")?;
        }
        Ok(())
    }
}

impl<'a> Display for FileName<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.leading_separator)?;
        write!(f, "{}", self.segment)?;
        if let Some(ext) = &self.ext_excluding_dot {
            write!(f, ".{ext}")?;
        }
        if let Some(loc) = &self.location {
            write!(f, "{loc}")?;
        }
        Ok(())
    }
}

impl<'a> Display for Path<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let Self {
            drive_excluding_colon,
            segments,
            filename,
        } = self;

        if let Some(drive) = &drive_excluding_colon {
            write!(f, "{drive}:")?;
        }

        for segment in segments {
            write!(f, "{segment}")?;
        }
        write!(f, "{filename}")
    }
}

impl<'a> Display for Number<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let Self {
            number,
            suffix_without_underscore,
        } = self;
        write!(f, "{number}")?;
        if let Some(suffix) = suffix_without_underscore {
            write!(f, "_")?;
            write!(f, "{suffix}")?;
        }

        Ok(())
    }
}

impl<'a> Display for Atom<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Atom::Text(text) => write!(f, "{text}"),
        }
    }
}

impl<'a> Display for Token<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Token::Number(number) => write!(f, "{number}"),
            Token::True => write!(f, "true"),
            Token::False => write!(f, "false"),
            Token::None => write!(f, "None"),
            Token::Atom(atom) => write!(f, "{atom}"),
            Token::Path(path) => write!(f, "{path}"),
            Token::Separated {
                before,
                space_before,
                separator,
                after,
            } => write!(f, "{before}{space_before}{separator}{after}"),
            Token::Delimited(delimited) => write!(f, "{delimited}"),
            Token::String(s) => write!(f, "{s}"),
            Token::Lifetime(s) => write!(f, "'{s}"),
        }
    }
}

impl<'a> Display for Delimited<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some((prefix, space)) = &self.prefix {
            write!(f, "{prefix}")?;
            write!(f, "{space}")?;
        }
        self.delimiter.fmt_start(f)?;
        write!(f, "{}", self.contents)?;
        self.delimiter.fmt_end(f)
    }
}

impl<'a> Display for Segment<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.leading_space)?;
        write!(f, "{}", self.token)
    }
}

impl<'a> Display for Segments<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for segment in &self.segments {
            write!(f, "{segment}")?;
        }
        write!(f, "{}", self.trailing_space)
    }
}