use super::*;
#[derive(Clone, Debug, Default)]
#[repr(transparent)]
pub struct Directory(Vec<Descriptor>);
impl AsRef<[Descriptor]> for Directory {
#[inline]
fn as_ref(&self) -> &[Descriptor] {
&self.0
}
}
impl AsMut<[Descriptor]> for Directory {
#[inline]
fn as_mut(&mut self) -> &mut [Descriptor] {
&mut self.0
}
}
impl From<Vec<Descriptor>> for Directory {
#[inline]
fn from(dir: Vec<Descriptor>) -> Directory {
Directory(dir)
}
}
impl From<Directory> for Vec<Descriptor> {
#[inline]
fn from(this: Directory) -> Vec<Descriptor> {
this.0
}
}
impl ops::Deref for Directory {
type Target = [Descriptor];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Directory {
#[inline]
pub(crate) fn as_blocks(&self) -> &[Block] {
unsafe {
slice::from_raw_parts(self.0.as_ptr() as *const Block, self.0.len() * Descriptor::BLOCKS_LEN)
}
}
#[inline]
pub(crate) fn as_blocks_mut(&mut self) -> &mut [Block] {
unsafe {
slice::from_raw_parts_mut(self.0.as_mut_ptr() as *mut Block, self.0.len() * Descriptor::BLOCKS_LEN)
}
}
#[inline]
pub fn find_desc(&self, path: &[u8]) -> Option<&Descriptor> {
dir::find_desc(&self.0, path)
}
#[inline]
pub fn find_file(&self, path: &[u8]) -> Option<&Descriptor> {
match dir::find_desc(&self.0, path) {
Some(desc) if desc.is_file() => Some(desc),
_ => None
}
}
#[inline]
pub fn get_children(&self, path: &[u8]) -> Option<&[Descriptor]> {
dir::find_dir(&self.0, path)
}
#[inline]
pub fn display(&self) -> impl '_ + fmt::Display {
dir::DirFmt::new(".", &self.0, &dir::TreeArt::UNICODE)
}
#[inline]
pub fn display_children<'a>(&'a self, path: Option<&'a str>, art: &'a dir::TreeArt<'static>) -> Option<impl 'a + fmt::Display> {
let children = match path {
Some(path) => dir::find_dir(&self.0, path.as_bytes())?,
None => &self.0,
};
Some(dir::DirFmt::new(path.unwrap_or("."), children, art))
}
#[inline]
pub fn fsck(&self, high_mark: u32, log: &mut dyn fmt::Write) -> bool {
dir::fsck(&self.0, high_mark, log)
}
}
impl Directory {
#[inline]
pub const fn new() -> Directory {
Directory(Vec::new())
}
#[inline]
pub(crate) fn create(&mut self, path: &[u8]) -> &mut Descriptor {
dir::create(&mut self.0, path)
}
#[inline]
pub fn create_link(&mut self, path: &[u8], file_desc: &Descriptor) {
if file_desc.is_file() {
let desc = dir::create(&mut self.0, path);
desc.content_size = file_desc.content_size;
desc.content_type = file_desc.content_type;
desc.section = file_desc.section;
}
}
#[inline]
pub fn create_dir(&mut self, path: &[u8]) {
let desc = dir::create(&mut self.0, path);
desc.content_type = 0;
desc.content_size = 0;
desc.section = Section::default();
}
#[inline]
pub fn remove(&mut self, path: &[u8]) -> Option<Descriptor> {
dir::remove(&mut self.0, path)
}
pub fn move_file(&mut self, src_path: &[u8], dest_path: &[u8]) -> bool {
match dir::find_desc(&self.0, src_path) {
Some(src_desc) if src_desc.is_file() => (),
_ => return false,
}
let deleted = match dir::remove(&mut self.0, src_path) {
Some(deleted) => deleted,
None => return false,
};
let desc = dir::create(&mut self.0, dest_path);
desc.content_type = deleted.content_type;
desc.content_size = deleted.content_size;
desc.section = deleted.section;
return true;
}
}
#[cfg(test)]
mod tests;