use crate::error::{VBError, VBResult};
use crate::state::file;
use crate::value::VBVariant;
use std::io;
use vb6core::error::err_number;
pub fn unlock_file(file_number: VBVariant, record_range: VBVariant) -> VBResult<()> {
let file_num = match file_number {
VBVariant::Integer(n) => n,
VBVariant::Long(n) => n as i16,
VBVariant::Byte(n) => n as i16,
_ => {
return Err(VBError::with_description(
err_number::TYPE_MISMATCH,
"Type mismatch in Unlock statement",
));
}
};
if !(file::MIN_FILE_NUMBER..=file::MAX_FILE_NUMBER).contains(&file_num) {
return Err(VBError::with_description(
err_number::BAD_FILE_NAME_OR_NUMBER,
"Bad file name or number",
));
}
if !file::is_file_open(file_num) {
return Err(VBError::with_description(
err_number::BAD_FILE_NAME_OR_NUMBER,
"File not open",
));
}
let range = super::lock::parse_record_range(&record_range)?;
file::unlock_file(file_num, range).map_err(|e| {
VBError::with_description(
match e.kind() {
io::ErrorKind::NotFound => err_number::BAD_FILE_NAME_OR_NUMBER,
_ => 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 unlock_entire_file() {
let _guard = crate::state::test_support::lock_test();
let _ = file::close_all_files();
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("test.txt");
std::fs::write(&path, "Hello").unwrap();
file::open_file(
&path,
file::OpenMode::Random,
file::AccessMode::ReadWrite,
file::LockMode::Shared,
1,
1,
)
.unwrap();
let _ = file::lock_file(1, None);
unlock_file(VBVariant::Integer(1), VBVariant::Empty).unwrap();
let _ = file::close_all_files();
}
#[test]
fn unlock_rejects_bad_file_number() {
let _guard = crate::state::test_support::lock_test();
let result = unlock_file(VBVariant::Integer(999), VBVariant::Empty);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().number,
err_number::BAD_FILE_NAME_OR_NUMBER
);
}
#[test]
fn unlock_rejects_non_numeric() {
let _guard = crate::state::test_support::lock_test();
let result = unlock_file(VBVariant::from_string("abc"), VBVariant::Empty);
assert!(result.is_err());
assert_eq!(result.unwrap_err().number, err_number::TYPE_MISMATCH);
}
}