use crate::error::{VBError, VBResult};
use crate::state::file;
use crate::value::VBVariant;
use vb6core::error::err_number;
pub fn chdir(path: &VBVariant) -> VBResult<()> {
let path_str = match path {
VBVariant::String(s) => s.as_str().to_string(),
_ => {
return Err(VBError::with_description(
err_number::TYPE_MISMATCH,
"Type mismatch in ChDir",
));
}
};
if path_str.len() >= 2 && path_str.as_bytes()[1] == b':' {
let drive = path_str.as_bytes()[0] as char;
file::set_current_drive(drive).map_err(|e| {
VBError::with_description(
match e.kind() {
std::io::ErrorKind::NotFound => err_number::DEVICE_UNAVAILABLE,
_ => err_number::DEVICE_IO_ERROR,
},
e.to_string(),
)
})?;
}
let target = file::resolve_path(std::path::Path::new(&path_str));
file::set_current_dir(&target).map_err(|e| {
VBError::with_description(
match e.kind() {
std::io::ErrorKind::NotFound => err_number::PATH_NOT_FOUND,
std::io::ErrorKind::PermissionDenied => err_number::PERMISSION_DENIED,
_ => err_number::DEVICE_IO_ERROR,
},
e.to_string(),
)
})?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::state::file::{self};
use vb6core::error::err_number;
#[test]
fn chdir_changes_directory() {
let _guard = crate::state::test_support::lock_test();
let dir = tempfile::tempdir().unwrap();
let subdir = dir.path().join("subdir");
std::fs::create_dir(&subdir).unwrap();
file::set_root(dir.path());
chdir(&VBVariant::from_string("subdir")).unwrap();
let cwd = file::current_dir().unwrap();
assert_eq!(cwd, subdir);
}
#[test]
fn chdir_rejects_nonexistent_directory() {
let _guard = crate::state::test_support::lock_test();
let dir = tempfile::tempdir().unwrap();
file::set_root(dir.path());
let result = chdir(&VBVariant::from_string("nonexistent"));
assert!(result.is_err());
assert_eq!(result.unwrap_err().number, err_number::PATH_NOT_FOUND);
}
#[test]
fn chdir_rejects_non_string() {
let _guard = crate::state::test_support::lock_test();
let result = chdir(&VBVariant::Long(42));
assert!(result.is_err());
assert_eq!(result.unwrap_err().number, err_number::TYPE_MISMATCH);
}
}