Skip to main content

qwencode_rs/utils/
helpers.rs

1use std::path::PathBuf;
2
3/// Get the default QwenCode executable path
4pub fn get_default_qwen_path() -> Option<PathBuf> {
5    // Try common locations
6    let candidates = vec!["qwen", "qwen-code"];
7
8    for candidate in candidates {
9        if which(candidate).is_some() {
10            return Some(PathBuf::from(candidate));
11        }
12    }
13
14    None
15}
16
17/// Check if an executable exists in PATH
18fn which(executable: &str) -> Option<PathBuf> {
19    // Simple implementation - in production, use the `which` crate
20    std::env::var_os("PATH").and_then(|paths| {
21        std::env::split_paths(&paths)
22            .filter_map(|dir| {
23                let full_path = dir.join(executable);
24                if full_path.is_file() {
25                    Some(full_path)
26                } else {
27                    None
28                }
29            })
30            .next()
31    })
32}
33
34/// Format a duration in milliseconds to a human-readable string
35pub fn format_duration_ms(ms: u64) -> String {
36    if ms < 1000 {
37        format!("{}ms", ms)
38    } else if ms < 60_000 {
39        format!("{:.1}s", ms as f64 / 1000.0)
40    } else {
41        let minutes = ms / 60_000;
42        let seconds = (ms % 60_000) / 1000;
43        format!("{}m {}s", minutes, seconds)
44    }
45}
46
47/// Convert a string to a path buffer
48pub fn string_to_path(s: &str) -> PathBuf {
49    PathBuf::from(s)
50}
51
52/// Check if running in debug mode
53pub fn is_debug_mode() -> bool {
54    cfg!(debug_assertions)
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn test_format_duration_ms_less_than_second() {
63        assert_eq!(format_duration_ms(500), "500ms");
64        assert_eq!(format_duration_ms(1), "1ms");
65        assert_eq!(format_duration_ms(999), "999ms");
66    }
67
68    #[test]
69    fn test_format_duration_ms_less_than_minute() {
70        assert_eq!(format_duration_ms(1000), "1.0s");
71        assert_eq!(format_duration_ms(1500), "1.5s");
72        assert_eq!(format_duration_ms(59999), "60.0s");
73    }
74
75    #[test]
76    fn test_format_duration_ms_minutes() {
77        assert_eq!(format_duration_ms(60000), "1m 0s");
78        assert_eq!(format_duration_ms(90000), "1m 30s");
79        assert_eq!(format_duration_ms(120000), "2m 0s");
80    }
81
82    #[test]
83    fn test_string_to_path() {
84        let path = string_to_path("/tmp/test");
85        assert_eq!(path, PathBuf::from("/tmp/test"));
86    }
87
88    #[test]
89    fn test_is_debug_mode() {
90        // Should be true in test builds
91        let _ = is_debug_mode();
92    }
93
94    #[test]
95    fn test_get_default_qwen_path_returns_option() {
96        // May or may not find qwen, but should return an Option
97        let result = get_default_qwen_path();
98        assert!(result.is_none() || result.is_some());
99    }
100}