nut_shell/shell/
handler.rs1use crate::config::ShellConfig;
7use crate::error::CliError;
8use crate::response::Response;
9
10pub trait CommandHandler<C: ShellConfig> {
13 fn execute_sync(&self, id: &str, args: &[&str]) -> Result<Response<C>, CliError>;
15
16 #[cfg(feature = "async")]
19 #[allow(async_fn_in_trait)]
20 async fn execute_async(&self, id: &str, args: &[&str]) -> Result<Response<C>, CliError>;
21}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26 use crate::config::DefaultConfig;
27
28 struct TestHandler;
30
31 impl CommandHandler<DefaultConfig> for TestHandler {
32 fn execute_sync(
33 &self,
34 id: &str,
35 _args: &[&str],
36 ) -> Result<Response<DefaultConfig>, CliError> {
37 match id {
38 "test" => Ok(Response::success("OK")),
39 _ => Err(CliError::CommandNotFound),
40 }
41 }
42
43 #[cfg(feature = "async")]
44 async fn execute_async(
45 &self,
46 id: &str,
47 _args: &[&str],
48 ) -> Result<Response<DefaultConfig>, CliError> {
49 match id {
50 "async-test" => Ok(Response::success("Async OK")),
51 _ => Err(CliError::CommandNotFound),
52 }
53 }
54 }
55
56 #[test]
57 fn test_sync_handler() {
58 let handler = TestHandler;
59 let result = handler.execute_sync("test", &[]);
60 assert!(result.is_ok());
61 assert_eq!(result.unwrap().message.as_str(), "OK");
62
63 let result = handler.execute_sync("unknown", &[]);
64 assert_eq!(result, Err(CliError::CommandNotFound));
65 }
66
67 #[cfg(feature = "async")]
68 #[tokio::test]
69 async fn test_async_handler() {
70 let handler = TestHandler;
71 let result = handler.execute_async("async-test", &[]).await;
72 assert!(result.is_ok());
73 assert_eq!(result.unwrap().message.as_str(), "Async OK");
74
75 let result = handler.execute_async("unknown", &[]).await;
76 assert_eq!(result, Err(CliError::CommandNotFound));
77 }
78}