zeph_commands/handlers/
cd.rs1use std::future::Future;
7use std::pin::Pin;
8
9use crate::context::CommandContext;
10use crate::{CommandError, CommandHandler, CommandOutput, SlashCategory};
11
12pub struct CdCommand;
20
21impl CommandHandler<CommandContext<'_>> for CdCommand {
22 fn name(&self) -> &'static str {
23 "/cd"
24 }
25
26 fn description(&self) -> &'static str {
27 "Change the session's working directory (no arg: show current)"
28 }
29
30 fn args_hint(&self) -> &'static str {
31 "[path]"
32 }
33
34 fn category(&self) -> SlashCategory {
35 SlashCategory::Session
36 }
37
38 fn requires_auth(&self) -> bool {
39 true
40 }
41
42 fn handle<'a>(
43 &'a self,
44 ctx: &'a mut CommandContext<'_>,
45 args: &'a str,
46 ) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
47 Box::pin(async move {
51 let result = ctx.agent.change_working_directory(args).await?;
52 Ok(CommandOutput::Message(result))
53 })
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::handlers::test_helpers::{MockDebug, MockMessages, MockSession, make_ctx};
61 use crate::sink::NullSink;
62
63 #[test]
64 fn cd_name_and_description() {
65 assert_eq!(CdCommand.name(), "/cd");
66 assert!(!CdCommand.description().is_empty());
67 }
68
69 #[test]
70 fn cd_requires_auth() {
71 assert!(CdCommand.requires_auth());
72 }
73
74 #[tokio::test]
75 async fn cd_returns_message() {
76 let mut sink = NullSink;
77 let mut debug = MockDebug;
78 let mut messages = MockMessages;
79 let session = MockSession;
80 let mut agent = crate::NullAgent;
81 let mut ctx = make_ctx(&mut sink, &mut debug, &mut messages, &session, &mut agent);
82 let out = CdCommand.handle(&mut ctx, "").await;
85 assert!(out.is_err());
86 }
87}