qubit-fs 0.2.2

Provider-neutral synchronous and asynchronous filesystem abstraction for Rust
Documentation
// =============================================================================
//    Copyright (c) 2026 Haixing Hu.
//
//    SPDX-License-Identifier: Apache-2.0
//
//    Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Pure matching rules shared by listing streams.
use crate::directory::ListFilter;
use crate::directory::ListOptions;
use crate::directory::ListScope;
use crate::metadata::DirEntry;
use crate::path::Path;
use crate::path::PathSemantics;
/// Returns the entry suffix only when it lies within the requested namespace.
pub(crate) fn relative_path<'a>(scope: &ListScope, entry: &'a Path, semantics: PathSemantics) -> Option<&'a str> {
    let Some(root) = scope.path() else {
        return Some(entry.as_str());
    };
    if matches!(semantics, PathSemantics::ObjectKey | PathSemantics::ProviderSpecific) {
        return entry.as_str().strip_prefix(root.as_str());
    }
    if root == entry {
        Some("")
    } else if root.as_str() == "/" {
        entry.as_str().strip_prefix('/')
    } else {
        let remainder = entry.as_str().strip_prefix(root.as_str())?;
        if root.as_str().ends_with('/') {
            Some(remainder)
        } else {
            remainder.strip_prefix('/')
        }
    }
}
/// Validates a provider entry against selection and metadata requirements.
///
/// # Errors
/// Returns a fixed diagnostic when the provider entry violates the request.
pub(crate) fn select(
    entry: &DirEntry,
    scope: &ListScope,
    options: &ListOptions,
    semantics: PathSemantics,
) -> Result<(), &'static str> {
    let Some(relative) = relative_path(scope, &entry.path, semantics) else {
        return Err("provider returned directory entry outside requested root");
    };
    match (semantics, options.filter()) {
        (PathSemantics::Hierarchical, Some(ListFilter::Subtree(prefix)))
            if !(relative == prefix || relative.strip_prefix(prefix).is_some_and(|rest| rest.starts_with('/'))) =>
        {
            return Err("provider returned directory entry outside requested prefix");
        }
        (PathSemantics::Hierarchical, Some(ListFilter::LiteralPrefix(_))) => {
            return Err("literal prefix is not valid for hierarchical listing");
        }
        (PathSemantics::ObjectKey | PathSemantics::ProviderSpecific, Some(ListFilter::LiteralPrefix(prefix)))
            if !relative.starts_with(prefix) =>
        {
            return Err("provider returned directory entry outside requested prefix");
        }
        (PathSemantics::ObjectKey | PathSemantics::ProviderSpecific, Some(ListFilter::Subtree(_))) => {
            return Err("subtree filter is not valid for flat listing");
        }
        _ => {}
    }
    if !options.recursive() && options.filter().is_none() && relative.contains('/') {
        return Err("provider returned nested directory entry for non-recursive listing");
    }
    if options.include_metadata() && entry.metadata.is_none() {
        return Err("provider returned directory entry without requested metadata");
    }
    Ok(())
}