Skip to main content

minus/
error.rs

1//! Provides error types that are used in various places
2//!
3//! Some types provided are just present there to avoid leaking
4//! upstream error types
5
6use crate::minus_core::commands::Command;
7use std::io;
8
9/// An operation on the terminal failed, for example resizing it.
10///
11/// You can get more information about this error by calling
12/// [`source`](std::error::Error::source) on it.
13#[derive(Debug, thiserror::Error)]
14#[error(transparent)]
15#[allow(clippy::module_name_repetitions)]
16pub struct TermError(
17    // This member is private to avoid leaking the crossterm error type up the
18    // dependency chain.
19    #[from] io::Error,
20);
21
22/// There was an error while compiling the regex
23#[derive(Debug, thiserror::Error)]
24#[error(transparent)]
25#[allow(clippy::module_name_repetitions)]
26#[cfg(feature = "search")]
27#[cfg_attr(docsrs, doc(cfg(feature = "search")))]
28pub struct RegexError(
29    // This member is private to avoid leaking the regex error type up the
30    // dependency chain.
31    #[from] regex::Error,
32);
33
34/// Errors that can occur during setup.
35#[derive(Debug, thiserror::Error)]
36#[allow(clippy::module_name_repetitions)]
37pub enum SetupError {
38    #[error("The standard output is not a valid terminal")]
39    InvalidTerminal,
40
41    #[error("Failed to switch to alternate screen")]
42    AlternateScreen(TermError),
43
44    #[error("Failed to enable raw mode")]
45    RawMode(TermError),
46
47    #[error("Failed to hide the cursor")]
48    HideCursor(TermError),
49
50    #[error("Failed to enable mouse capture")]
51    EnableMouseCapture(TermError),
52
53    #[error("Couldn't determine the terminal size")]
54    TerminalSize(TermError),
55}
56
57/// Errors that can occur during clean up.
58#[derive(Debug, thiserror::Error)]
59#[allow(clippy::module_name_repetitions)]
60pub enum CleanupError {
61    #[error("Failed to disable mouse capture")]
62    DisableMouseCapture(TermError),
63
64    #[error("Failed to show the cursor")]
65    ShowCursor(TermError),
66
67    #[error("Failed to disable raw mode")]
68    DisableRawMode(TermError),
69
70    #[error("Failed to switch back to main screen")]
71    LeaveAlternateScreen(TermError),
72}
73
74/// Errors that can happen during runtime.
75#[derive(Debug, thiserror::Error)]
76#[allow(clippy::module_name_repetitions)]
77pub enum MinusError {
78    #[error("Failed to initialize the terminal")]
79    Setup(#[from] SetupError),
80
81    #[error("Failed to clean up the terminal")]
82    Cleanup(#[from] CleanupError),
83
84    #[error("Failed to draw the new data")]
85    Draw(#[from] std::io::Error),
86
87    #[error("Failed to handle terminal event")]
88    HandleEvent(TermError),
89
90    #[error("Failed to do an operation on the cursor")]
91    Cursor(#[from] TermError),
92
93    #[error("Failed to send formatted data to the pager")]
94    FmtWriteError(#[from] std::fmt::Error),
95
96    #[error("Failed to send data to the receiver")]
97    Communication(#[from] crossbeam_channel::SendError<Command>),
98
99    #[error("Failed to convert between some primitives")]
100    Conversion,
101
102    #[error(transparent)]
103    #[cfg(feature = "search")]
104    #[cfg_attr(docsrs, doc(cfg(feature = "search")))]
105    SearchExpError(#[from] RegexError),
106
107    #[cfg(test)]
108    #[error(transparent)]
109    #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
110    JoinError(#[from] tokio::task::JoinError),
111}
112
113// Just for  convenience helper which is useful in many places
114#[cfg(feature = "search")]
115impl From<regex::Error> for MinusError {
116    fn from(e: regex::Error) -> Self {
117        Self::SearchExpError(RegexError::from(e))
118    }
119}