use crate::Ext4;
use crate::dir_entry::DirEntryName;
use crate::dir_htree::get_dir_entry_via_htree;
use crate::error::Ext4Error;
use crate::inode::{Inode, InodeFlags};
use crate::iters::read_dir::ReadDir;
use crate::path::PathBuf;
pub(crate) fn get_dir_entry_inode_by_name(
fs: &Ext4,
dir_inode: &Inode,
name: DirEntryName<'_>,
) -> Result<Inode, Ext4Error> {
assert!(dir_inode.metadata.is_dir());
if dir_inode.flags.contains(InodeFlags::DIRECTORY_ENCRYPTED) {
return Err(Ext4Error::Encrypted);
}
if dir_inode.flags.contains(InodeFlags::DIRECTORY_HTREE) {
let entry = get_dir_entry_via_htree(fs, dir_inode, name)?;
return Inode::read(fs, entry.inode);
}
let path = PathBuf::empty();
for entry in ReadDir::new(fs.clone(), dir_inode, path)? {
let entry = entry?;
if entry.file_name() == name {
return Inode::read(fs, entry.inode);
}
}
Err(Ext4Error::NotFound)
}
#[cfg(feature = "std")]
#[cfg(test)]
mod tests {
use super::*;
use crate::test_util::load_test_disk1;
#[test]
fn test_get_dir_entry_inode_by_name() {
let fs = load_test_disk1();
let root_inode = fs.read_root_inode().unwrap();
let lookup = |name| {
get_dir_entry_inode_by_name(
&fs,
&root_inode,
DirEntryName::try_from(name).unwrap(),
)
};
assert_eq!(lookup(".").unwrap().index, root_inode.index);
assert_eq!(lookup("..").unwrap().index, root_inode.index);
assert!(lookup("empty_file").is_ok());
assert!(lookup("empty_dir").is_ok());
let err = lookup("does_not_exist").unwrap_err();
assert!(matches!(err, Ext4Error::NotFound));
}
}