terminal_colorsaurus/
error.rs

1use crate::fmt::CaretNotation;
2use core::fmt;
3use std::time::Duration;
4use std::{error, io};
5
6/// An error returned by this library.
7#[derive(Debug)]
8#[non_exhaustive]
9pub enum Error {
10    /// I/O error
11    Io(io::Error),
12    /// The terminal responded using an unsupported response format.
13    Parse(Vec<u8>),
14    /// The query timed out. This can happen because \
15    /// either the terminal does not support querying for colors \
16    /// or the terminal has a lot of latency (e.g. when connected via SSH).
17    Timeout(Duration),
18    /// The terminal does not support querying for the foreground or background color.
19    UnsupportedTerminal(UnsupportedTerminalError),
20}
21
22impl error::Error for Error {
23    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
24        match self {
25            Error::Io(source) => Some(source),
26            Error::UnsupportedTerminal(source) => Some(source),
27            _ => None,
28        }
29    }
30}
31
32impl fmt::Display for Error {
33    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34        match self {
35            Error::Io(e) => write!(f, "I/O error: {e}"),
36            Error::Parse(data) => write!(
37                f,
38                "failed to parse response: {0}",
39                // FIXME(msrv): [1.79.0] Use `.utf8_chunks()` to avoid allocating.
40                CaretNotation(String::from_utf8_lossy(data).as_ref()),
41            ),
42            #[allow(clippy::use_debug)]
43            Error::Timeout(timeout) => {
44                write!(f, "operation did not complete within {timeout:?}")
45            }
46            Error::UnsupportedTerminal(e) => fmt::Display::fmt(e, f),
47        }
48    }
49}
50
51impl From<io::Error> for Error {
52    fn from(source: io::Error) -> Self {
53        Error::Io(source)
54    }
55}
56
57impl Error {
58    pub(crate) fn unsupported() -> Self {
59        Error::UnsupportedTerminal(UnsupportedTerminalError)
60    }
61}
62
63#[derive(Debug)]
64#[non_exhaustive]
65pub struct UnsupportedTerminalError;
66
67impl error::Error for UnsupportedTerminalError {}
68
69impl fmt::Display for UnsupportedTerminalError {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        f.write_str("the terminal does not support querying for its colors")
72    }
73}