use crate::error::{VBError, VBResult};
use crate::state::file;
use crate::value::VBVariant;
use vb6core::error::err_number;
pub fn name_statement(old_pathname: &VBVariant, new_pathname: &VBVariant) -> VBResult<()> {
let old_str = match old_pathname {
VBVariant::String(s) => s.as_str().to_string(),
_ => {
return Err(VBError::with_description(
13, "Type mismatch in Name statement",
));
}
};
let new_str = match new_pathname {
VBVariant::String(s) => s.as_str().to_string(),
_ => {
return Err(VBError::with_description(
13, "Type mismatch in Name statement",
));
}
};
if !file::file_exists(std::path::Path::new(&old_str)) {
return Err(VBError::with_description(
53, format!("File not found: {}", old_str),
));
}
if file::file_exists(std::path::Path::new(&new_str)) {
return Err(VBError::with_description(
75, format!("File already exists: {}", new_str),
));
}
file::rename_file(
std::path::Path::new(&old_str),
std::path::Path::new(&new_str),
)
.map_err(|e| {
VBError::with_description(
match e.kind() {
std::io::ErrorKind::NotFound => err_number::FILE_NOT_FOUND, std::io::ErrorKind::PermissionDenied => err_number::PERMISSION_DENIED, _ => err_number::PATH_FILE_ACCESS_ERROR, },
e.to_string(),
)
})?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::state::file::{self};
use vb6core::error::err_number;
#[test]
fn name_renames_file() {
let _guard = crate::state::test_support::lock_test();
let dir = tempfile::tempdir().unwrap();
file::set_root(dir.path());
std::fs::write(dir.path().join("old.txt"), "Hello").unwrap();
name_statement(
&VBVariant::from_string("old.txt"),
&VBVariant::from_string("new.txt"),
)
.unwrap();
assert!(!dir.path().join("old.txt").exists());
assert!(dir.path().join("new.txt").exists());
let content = std::fs::read_to_string(dir.path().join("new.txt")).unwrap();
assert_eq!(content, "Hello");
}
#[test]
fn name_rejects_nonexistent_source() {
let _guard = crate::state::test_support::lock_test();
let dir = tempfile::tempdir().unwrap();
file::set_root(dir.path());
let result = name_statement(
&VBVariant::from_string("nonexistent.txt"),
&VBVariant::from_string("new.txt"),
);
assert!(result.is_err());
assert_eq!(result.unwrap_err().number, err_number::FILE_NOT_FOUND);
}
#[test]
fn name_rejects_existing_destination() {
let _guard = crate::state::test_support::lock_test();
let dir = tempfile::tempdir().unwrap();
file::set_root(dir.path());
std::fs::write(dir.path().join("old.txt"), "Hello").unwrap();
std::fs::write(dir.path().join("new.txt"), "World").unwrap();
let result = name_statement(
&VBVariant::from_string("old.txt"),
&VBVariant::from_string("new.txt"),
);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().number,
err_number::PATH_FILE_ACCESS_ERROR
);
}
#[test]
fn name_rejects_non_string() {
let _guard = crate::state::test_support::lock_test();
let result = name_statement(&VBVariant::Long(42), &VBVariant::from_string("new.txt"));
assert!(result.is_err());
assert_eq!(result.unwrap_err().number, err_number::TYPE_MISMATCH);
let result = name_statement(&VBVariant::from_string("old.txt"), &VBVariant::Long(42));
assert!(result.is_err());
assert_eq!(result.unwrap_err().number, err_number::TYPE_MISMATCH);
}
}