lamexfat 0.1.0

no_std read-only exFAT reader for UEFI bootloaders (removable media)
Documentation
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Path resolution: walk `/`-separated components from the root directory to the
//! target entry set.

use crate::{
    block_read::BlockRead,
    dir::{read_entries, EntrySet},
    error::{Error, Result},
    name::name_eq,
    path::Path,
    upcase::Upcase,
    vbr::Geometry,
};

/// Resolve `path` to its entry set. Returns `None` for the root directory itself
/// (a path with no components), which has no on-disk entry set.
pub(crate) fn resolve(
    reader: &mut impl BlockRead,
    geo: &Geometry,
    upcase: &Upcase,
    path: Path<'_>,
) -> Result<Option<EntrySet>> {
    let mut cluster = geo.root_cluster;
    let mut contiguous = false; // the root directory uses the FAT chain
    let mut found: Option<EntrySet> = None;

    for comp in path.components() {
        // Descend only through directories.
        if let Some(es) = &found {
            if !es.is_dir {
                return Err(Error::NotFound {
                    component: "non-directory in path",
                });
            }
        }
        let entries = read_entries(reader, geo, cluster, contiguous)?;
        let next = entries
            .into_iter()
            .find(|es| name_eq(comp, &es.name, upcase))
            .ok_or(Error::NotFound { component: "path" })?;
        cluster = next.first_cluster;
        contiguous = next.contiguous;
        found = Some(next);
    }
    Ok(found)
}