erofs-rs 0.2.1

A pure Rust library for reading EROFS (Enhanced Read-Only File System) images
Documentation
use alloc::vec::Vec;
use typed_path::{UnixPath, UnixPathBuf};

use super::EroFS;
use crate::backend::AsyncImage;
use crate::dirent::{DirEntry, DirentBlock};
use crate::{Result, types::Inode};

pub struct ReadDir<'a, I: AsyncImage> {
    dir: UnixPathBuf,
    inode: Inode,
    erofs: &'a EroFS<I>,
    dirent_block: DirentBlock<Vec<u8>>,
    offset: usize,
}

impl<'a, I: AsyncImage> ReadDir<'a, I> {
    pub(crate) async fn new<P: AsRef<UnixPath>>(
        erofs: &'a EroFS<I>,
        inode: Inode,
        dir: P,
    ) -> Result<Self> {
        let block_data = erofs.read_inode_block(&inode, 0).await?;
        let dirent_block = DirentBlock::new(dir.as_ref().to_path_buf(), block_data)?;
        Ok(Self {
            dir: dir.as_ref().to_path_buf(),
            inode,
            erofs,
            dirent_block,
            offset: 0,
        })
    }

    pub async fn next_entry(&mut self) -> Result<Option<DirEntry>> {
        if self.offset >= self.inode.data_size() {
            return Ok(None);
        }

        while self.offset < self.inode.data_size() {
            match self.dirent_block.next_entry()? {
                Some(entry) => return Ok(Some(entry)),
                None => {
                    self.offset += self.dirent_block.block_size();
                    if self.offset < self.inode.data_size() {
                        let block_data = self
                            .erofs
                            .read_inode_block(&self.inode, self.offset)
                            .await?;
                        self.dirent_block = DirentBlock::new(self.dir.clone(), block_data)?;
                    }
                }
            }
        }
        Ok(None)
    }
}