command_stream/commands/
cd.rs1use crate::commands::CommandContext;
4use crate::utils::{trace, CommandResult};
5use std::env;
6use std::path::PathBuf;
7
8pub async fn cd(ctx: CommandContext) -> CommandResult {
12 let target = if ctx.args.is_empty() {
13 env::var("HOME")
15 .or_else(|_| env::var("USERPROFILE"))
16 .unwrap_or_else(|_| "/".to_string())
17 } else {
18 ctx.args[0].clone()
19 };
20
21 trace(
22 "VirtualCommand",
23 &format!("cd: changing directory to {:?}", target),
24 );
25
26 let path = PathBuf::from(&target);
27
28 match env::set_current_dir(&path) {
29 Ok(()) => {
30 let new_dir = env::current_dir()
31 .map(|p| p.display().to_string())
32 .unwrap_or_default();
33 trace(
34 "VirtualCommand",
35 &format!("cd: success, new dir: {}", new_dir),
36 );
37 CommandResult::success_empty()
39 }
40 Err(e) => {
41 trace("VirtualCommand", &format!("cd: failed: {}", e));
42 CommandResult::error(format!("cd: {}\n", e))
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use tempfile::tempdir;
51
52 #[tokio::test]
53 async fn test_cd_to_temp() {
54 let temp = tempdir().unwrap();
55 let temp_path = temp.path().to_string_lossy().to_string();
56 let original_dir = env::current_dir().unwrap();
57
58 let ctx = CommandContext::new(vec![temp_path.clone()]);
59 let result = cd(ctx).await;
60 assert!(result.is_success());
61 assert_eq!(result.stdout, "");
62
63 env::set_current_dir(original_dir).unwrap();
65 }
66
67 #[tokio::test]
68 async fn test_cd_to_nonexistent() {
69 let ctx = CommandContext::new(vec!["/nonexistent/path/12345".to_string()]);
70 let result = cd(ctx).await;
71 assert!(!result.is_success());
72 }
73}