use std::path::PathBuf;
use std::sync::atomic::AtomicU64;
pub(crate) static NEXT_SUBAGENT_ID: AtomicU64 = AtomicU64::new(1);
pub(crate) fn strip_ansi(s: &str) -> String {
let mut result = String::with_capacity(s.len());
let mut chars = s.chars().peekable();
while let Some(ch) = chars.next() {
if ch == '\x1b' {
match chars.peek() {
Some('[') => {
chars.next();
while let Some(&c) = chars.peek() {
chars.next();
if c.is_ascii_alphabetic() || c == '~' || c == '@' { break; }
}
}
Some(']') => {
chars.next();
while let Some(&c) = chars.peek() {
chars.next();
if c == '\x07' { break; }
if c == '\x1b' {
if chars.peek() == Some(&'\\') { chars.next(); }
break;
}
}
}
Some(_) => { chars.next(); } None => {}
}
} else {
result.push(ch);
}
}
result
}
pub(crate) fn expand_path(path: &str) -> PathBuf {
if path.starts_with("~/") {
if let Ok(home) = std::env::var("HOME") {
return PathBuf::from(home).join(path.strip_prefix("~/").unwrap());
}
} else if path == "~" {
if let Ok(home) = std::env::var("HOME") {
return PathBuf::from(home);
}
}
PathBuf::from(path)
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
#[test]
fn test_expand_path_home_prefix() {
let home = env::var("HOME").expect("HOME env var should be set");
let result = expand_path("~/foo");
assert_eq!(result, PathBuf::from(home).join("foo"));
}
#[test]
fn test_expand_path_tilde_alone() {
let home = env::var("HOME").expect("HOME env var should be set");
let result = expand_path("~");
assert_eq!(result, PathBuf::from(home));
}
#[test]
fn test_expand_path_absolute_unchanged() {
let result = expand_path("/absolute/path");
assert_eq!(result, PathBuf::from("/absolute/path"));
}
#[test]
fn test_expand_path_relative_unchanged() {
let result = expand_path("relative/path");
assert_eq!(result, PathBuf::from("relative/path"));
}
}