1use core::fmt;
4use std::{error::Error, io};
5
6pub type CustomUserError = Box<dyn Error + Send + Sync + 'static>;
9
10#[derive(Debug)]
12pub enum InquireError {
13 NotTTY,
16
17 InvalidConfiguration(String),
20
21 IO(io::Error),
23
24 OperationCanceled,
26
27 OperationInterrupted,
34
35 Custom(CustomUserError),
37}
38
39impl Error for InquireError {
40 fn source(&self) -> Option<&(dyn Error + 'static)> {
41 match self {
42 InquireError::IO(err) => Some(err),
43 InquireError::Custom(err) => Some(err.as_dyn_error()),
44 _ => None,
45 }
46 }
47}
48
49trait AsDynError<'a> {
50 fn as_dyn_error(&self) -> &(dyn Error + 'a);
51}
52
53impl<'a> AsDynError<'a> for dyn Error + Send + Sync + 'a {
54 #[inline]
55 fn as_dyn_error(&self) -> &(dyn Error + 'a) {
56 self
57 }
58}
59
60impl From<CustomUserError> for InquireError {
61 fn from(err: CustomUserError) -> Self {
62 InquireError::Custom(err)
63 }
64}
65
66impl From<io::Error> for InquireError {
67 fn from(err: io::Error) -> Self {
68 match err.raw_os_error() {
69 Some(25 | 6) => InquireError::NotTTY,
70 _ => InquireError::IO(err),
71 }
72 }
73}
74
75impl fmt::Display for InquireError {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 match self {
78 InquireError::NotTTY => f.write_str("The input device is not a TTY"),
79 InquireError::InvalidConfiguration(s) => {
80 write!(f, "The prompt configuration is invalid: {}", s)
81 }
82 InquireError::IO(err) => write!(f, "IO error: {}", err),
83 InquireError::OperationCanceled => f.write_str("Operation was canceled by the user"),
84 InquireError::OperationInterrupted => {
85 f.write_str("Operation was interrupted by the user")
86 }
87 InquireError::Custom(err) => write!(f, "User-provided error: {}", err),
88 }
89 }
90}
91
92pub type InquireResult<T> = Result<T, InquireError>;