embedded-exfat 0.4.0

ExFAT filesystem library with async support, mainly focusing on embedded system
Documentation
use core::fmt::Debug;
use core::mem;
use core::ops::Deref;

use super::super::meta::MetaFileDirectory;
use crate::error::Error;
use crate::fs::SectorIndex;
use crate::io::{self, Block, Wrap};
use crate::region::data::entry_type::RawEntryType;
use crate::region::data::entryset::{ENTRY_SIZE, RawEntry};

pub(crate) struct EntryIter<'a, IO> {
    meta: &'a mut MetaFileDirectory<IO>,
    entries: &'a [[RawEntry; 16]],
    pub sector_index: SectorIndex,
    pub index: u8,
}

#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
impl<'a, B: Deref<Target = [Block]>, E: Debug, IO> EntryIter<'a, IO>
where
    IO: io::IO<Block<'static> = B, Error = E>,
{
    pub async fn new(meta: &'a mut MetaFileDirectory<IO>) -> Result<EntryIter<'a, IO>, Error<E>> {
        let sector_index = meta.sector_index;
        let mut io = meta.io.acquire().await.wrap();
        let sector = io.read(sector_index.id(&meta.fs)).await?;
        let entries = unsafe { mem::transmute(&*sector) };
        drop(io);
        Ok(Self { meta, entries, sector_index, index: u8::MAX })
    }

    pub async fn skip(&mut self, num_entries: u8) -> Result<(), Error<E>> {
        self.index = self.index.wrapping_add(num_entries);
        let sector_size = self.meta.fs.sector_size() as usize;
        if (self.index as usize * ENTRY_SIZE) >= sector_size {
            self.index -= (sector_size / ENTRY_SIZE) as u8;
            self.sector_index = self.meta.next(self.sector_index).await?;
            let mut io = self.meta.io.acquire().await.wrap();
            let sector = io.read(self.sector_index.id(&self.meta.fs)).await?;
            self.entries = unsafe { mem::transmute(&*sector) };
        }
        Ok(())
    }

    pub async fn next(&mut self) -> Result<Option<&'a RawEntry>, Error<E>> {
        self.skip(1).await?;
        let index = self.index as usize;
        let entry = &self.entries[index / 16][index % 16];
        let entry_type: RawEntryType = entry[0].into();
        Ok(if !entry_type.is_end_of_directory() { Some(entry) } else { None })
    }
}