Skip to main content

styled_str/ansi_parser/
errors.rs

1use core::{fmt, num::ParseIntError, str::Utf8Error};
2
3use crate::alloc::String;
4
5/// Errors that can occur when processing terminal output.
6#[derive(Debug)]
7#[non_exhaustive]
8pub enum AnsiError {
9    /// Unfinished escape sequence.
10    UnfinishedSequence,
11    /// Unrecognized escape sequence (not a CSI or OSC one). The enclosed byte
12    /// is the first byte of the sequence (excluding `0x1b`).
13    UnrecognizedSequence(u8),
14    /// Invalid final byte for an SGR escape sequence.
15    InvalidSgrFinalByte(u8),
16    /// Unfinished color spec.
17    UnfinishedColor,
18    /// Invalid type of a color spec.
19    InvalidColorType(String),
20    /// Invalid ANSI color index.
21    InvalidColorIndex(ParseIntError),
22    /// UTF-8 decoding error.
23    Utf8(Utf8Error),
24}
25
26impl fmt::Display for AnsiError {
27    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
28        match self {
29            Self::UnfinishedSequence => formatter.write_str("Unfinished ANSI escape sequence"),
30            Self::UnrecognizedSequence(byte) => {
31                write!(
32                    formatter,
33                    "Unrecognized escape sequence (first byte is {byte})"
34                )
35            }
36            Self::InvalidSgrFinalByte(byte) => {
37                write!(
38                    formatter,
39                    "Invalid final byte for an SGR escape sequence: {byte}"
40                )
41            }
42            Self::UnfinishedColor => formatter.write_str("Unfinished color spec"),
43            Self::InvalidColorType(ty) => {
44                write!(formatter, "Invalid type of a color spec: {ty}")
45            }
46            Self::InvalidColorIndex(err) => {
47                write!(formatter, "Failed parsing color index: {err}")
48            }
49            Self::Utf8(err) => write!(formatter, "UTF-8 decoding error: {err}"),
50        }
51    }
52}
53
54#[cfg(feature = "std")]
55impl std::error::Error for AnsiError {
56    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
57        match self {
58            Self::InvalidColorIndex(err) => Some(err),
59            Self::Utf8(err) => Some(err),
60            _ => None,
61        }
62    }
63}
64
65impl From<Utf8Error> for AnsiError {
66    fn from(err: Utf8Error) -> Self {
67        Self::Utf8(err)
68    }
69}