streampager/
error.rs

1//! Error types.
2
3use std::ffi::OsStr;
4use std::result::Result as StdResult;
5use std::sync::mpsc::RecvError;
6use std::sync::mpsc::RecvTimeoutError;
7use std::sync::mpsc::SendError;
8use std::sync::mpsc::TryRecvError;
9
10use thiserror::Error;
11
12/// Convenient return type for functions.
13pub type Result<T> = StdResult<T, Error>;
14
15/// Main error type.
16#[derive(Debug, Error)]
17pub enum Error {
18    /// Comes from [Termwiz](https://crates.io/crates/termwiz).
19    #[error("terminal error")]
20    Termwiz(#[source] termwiz::Error),
21
22    /// Comes from [Regex](https://github.com/rust-lang/regex).
23    #[error("regex error")]
24    Regex(#[from] regex::Error),
25
26    /// Generic I/O error.
27    #[error("i/o error")]
28    Io(#[from] std::io::Error),
29
30    /// Returned when persisting a temporary file fails.
31    #[error(transparent)]
32    TempfilePersist(#[from] tempfile::PersistError),
33
34    /// Keymap-related error.
35    #[error("keymap error")]
36    Keymap(#[from] crate::keymap_error::KeymapError),
37
38    /// Binding-related error.
39    #[error("keybinding error")]
40    Binding(#[from] crate::bindings::BindingError),
41
42    /// Generic formatting error.
43    #[error(transparent)]
44    Fmt(#[from] std::fmt::Error),
45
46    /// Receive error on a channel.
47    #[error("channel error")]
48    ChannelRecv(#[from] RecvError),
49
50    /// Try-receive error on a channel.
51    #[error("channel error")]
52    ChannelTryRecv(#[from] TryRecvError),
53
54    /// Receive-timeout error on a channel.
55    #[error("channel error")]
56    ChannelRecvTimeout(#[from] RecvTimeoutError),
57
58    /// Send error on a channel.
59    #[error("channel error")]
60    ChannelSend,
61
62    /// Error returned if the terminfo database is missing.
63    #[error("terminfo database not found (is $TERM correct?)")]
64    TerminfoDatabaseMissing,
65
66    /// Wrapped error within the context of a command.
67    #[error("error running command '{command}'")]
68    WithCommand {
69        /// Wrapped error.
70        #[source]
71        error: Box<Self>,
72
73        /// Command the error is about.
74        command: String,
75    },
76
77    /// Wrapped error within the context of a file.
78    #[error("error loading file '{file}'")]
79    WithFile {
80        /// Wrapped error.
81        #[source]
82        error: Box<Self>,
83
84        /// File the error is about.
85        file: String,
86    },
87}
88
89impl Error {
90    #[cfg(feature = "load_file")]
91    pub(crate) fn with_file(self, file: impl AsRef<str>) -> Self {
92        Self::WithFile {
93            error: Box::new(self),
94            file: file.as_ref().to_owned(),
95        }
96    }
97
98    pub(crate) fn with_command(self, command: impl AsRef<OsStr>) -> Self {
99        Self::WithCommand {
100            error: Box::new(self),
101            command: command.as_ref().to_string_lossy().to_string(),
102        }
103    }
104}
105
106impl<T> From<SendError<T>> for Error {
107    fn from(_send_error: SendError<T>) -> Error {
108        Error::ChannelSend
109    }
110}