credent_cli_model/
error.rs

1use std::fmt;
2
3#[cfg(all(feature = "smol", not(feature = "tokio")))]
4type IoError = smol::io::Error;
5
6#[cfg(all(not(feature = "smol"), feature = "tokio"))]
7type IoError = tokio::io::Error;
8
9#[cfg(all(not(feature = "smol"), not(feature = "tokio")))]
10compile_error!(
11    r#"`credent` needs either the "backend-smol" or "backend-tokio" feature to be enabled."#
12);
13
14#[cfg(all(feature = "smol", feature = "tokio"))]
15compile_error!(
16    r#"Only one of "backend-smol" or "backend-tokio" should be enabled for `credent`.
17Maybe different crates are using different features?"#
18);
19
20/// Errors when using `credenti_cli`.
21#[derive(Debug)]
22pub enum Error {
23    /// Failed to write prompt to stderr.
24    PromptWrite {
25        /// Prompt to be written.
26        prompt: String,
27        /// Underlying error.
28        error: IoError,
29    },
30    /// Failed to flush stderr.
31    StdErrFlush(IoError),
32    /// Failed to read username.
33    UsernameRead(std::io::Error),
34    /// Failed to read password.
35    PasswordRead(std::io::Error),
36    /// Failed to read a plain text value from stdin.
37    PlainTextRead(std::io::Error),
38    /// Failed to read a secret value from stdin.
39    SecretRead(std::io::Error),
40
41    /// Tokio blocking task join error.
42    #[cfg(feature = "tokio")]
43    StdinReadJoin(tokio::task::JoinError),
44}
45
46impl fmt::Display for Error {
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        match self {
49            Self::PromptWrite { prompt, .. } => {
50                write!(f, "Failed to write prompt to stderr. Prompt: `{}`", prompt)
51            }
52            Self::StdErrFlush(..) => write!(f, "Failed to flush `stderr`."),
53            Self::UsernameRead(..) => write!(f, "Failed to read username from stdin."),
54            Self::PasswordRead(..) => write!(f, "Failed to read password from stdin."),
55            Self::PlainTextRead(..) => write!(f, "Failed to read value from stdin."),
56            Self::SecretRead(..) => write!(f, "Failed to read secret value from stdin."),
57
58            #[cfg(feature = "tokio")]
59            Self::StdinReadJoin(_) => write!(f, "Failed to wait for stdin task to complete."),
60        }
61    }
62}
63
64impl std::error::Error for Error {
65    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
66        match self {
67            Self::PromptWrite { error, .. } => Some(error),
68            Self::StdErrFlush(error) => Some(error),
69            Self::UsernameRead(error) => Some(error),
70            Self::PasswordRead(error) => Some(error),
71            Self::PlainTextRead(error) => Some(error),
72            Self::SecretRead(error) => Some(error),
73
74            #[cfg(feature = "tokio")]
75            Self::StdinReadJoin(error) => Some(error),
76        }
77    }
78}