1use core::fmt;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum CliError {
15 CommandNotFound,
17
18 InvalidPath,
22
23 InvalidArgumentCount {
25 expected_min: usize,
27 expected_max: usize,
29 received: usize,
31 },
32
33 InvalidArgumentFormat {
35 arg_index: usize,
37 expected: heapless::String<32>,
39 },
40
41 BufferFull,
43
44 PathTooDeep,
46
47 #[cfg(feature = "authentication")]
49 AuthenticationFailed,
50
51 #[cfg(feature = "authentication")]
53 NotAuthenticated,
54
55 IoError,
57
58 #[cfg(feature = "async")]
60 AsyncInSyncContext,
61
62 Timeout,
64
65 CommandFailed(heapless::String<128>),
67
68 Other(heapless::String<128>),
70}
71
72impl fmt::Display for CliError {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match self {
75 CliError::CommandNotFound => write!(f, "Command not found"),
76 CliError::InvalidPath => write!(f, "Invalid path"),
77 CliError::InvalidArgumentCount {
78 expected_min,
79 expected_max,
80 received,
81 } => {
82 if expected_min == expected_max {
83 write!(f, "Expected {} arguments, got {}", expected_min, received)
84 } else {
85 write!(
86 f,
87 "Expected {}-{} arguments, got {}",
88 expected_min, expected_max, received
89 )
90 }
91 }
92 CliError::InvalidArgumentFormat {
93 arg_index,
94 expected,
95 } => {
96 write!(f, "Argument {}: expected {}", arg_index + 1, expected)
97 }
98 CliError::BufferFull => write!(f, "Buffer full"),
99 CliError::PathTooDeep => write!(f, "Path too deep"),
100 #[cfg(feature = "authentication")]
101 CliError::AuthenticationFailed => write!(f, "Authentication failed"),
102 #[cfg(feature = "authentication")]
103 CliError::NotAuthenticated => write!(f, "Not authenticated"),
104 CliError::IoError => write!(f, "I/O error"),
105 #[cfg(feature = "async")]
106 CliError::AsyncInSyncContext => write!(f, "Async command requires async context"),
107 CliError::Timeout => write!(f, "Timeout"),
108 CliError::CommandFailed(msg) => write!(f, "{}", msg),
109 CliError::Other(msg) => write!(f, "{}", msg),
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 extern crate std;
118 use std::format;
119
120 #[test]
121 fn test_error_display() {
122 assert_eq!(
123 format!("{}", CliError::CommandNotFound),
124 "Command not found"
125 );
126 assert_eq!(format!("{}", CliError::InvalidPath), "Invalid path");
127
128 let err = CliError::InvalidArgumentCount {
129 expected_min: 2,
130 expected_max: 2,
131 received: 1,
132 };
133 assert_eq!(format!("{}", err), "Expected 2 arguments, got 1");
134
135 let err = CliError::InvalidArgumentCount {
136 expected_min: 1,
137 expected_max: 3,
138 received: 4,
139 };
140 assert_eq!(format!("{}", err), "Expected 1-3 arguments, got 4");
141
142 let mut expected = heapless::String::new();
143 expected.push_str("integer").unwrap();
144 let err = CliError::InvalidArgumentFormat {
145 arg_index: 0,
146 expected,
147 };
148 assert_eq!(format!("{}", err), "Argument 1: expected integer");
149
150 let mut expected = heapless::String::new();
151 expected.push_str("IP address").unwrap();
152 let err = CliError::InvalidArgumentFormat {
153 arg_index: 2,
154 expected,
155 };
156 assert_eq!(format!("{}", err), "Argument 3: expected IP address");
157 }
158}