qubit_fs/spi/resolved_list_options.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8// facade.
9//! Facade-resolved listing options.
10
11use crate::directory::ListOptions;
12use crate::metadata::SymlinkPolicy;
13
14/// Immutable options resolved by the facade before provider dispatch.
15///
16/// # Examples
17///
18/// ```rust
19/// use qubit_fs::directory::ListOptions;
20/// use qubit_fs::metadata::SymlinkPolicy;
21/// use qubit_fs::spi::ResolvedListOptions;
22///
23/// let options = ListOptions::default();
24/// assert!(std::any::type_name::<ResolvedListOptions>().contains("ResolvedListOptions"));
25/// assert_eq!(SymlinkPolicy::Reject, SymlinkPolicy::Reject);
26/// let _ = options;
27/// ```
28#[derive(Clone)]
29pub struct ResolvedListOptions {
30 /// Caller options retained after facade validation and normalization.
31 options: ListOptions,
32 /// Effective symbolic-link policy after applying the caller override.
33 symlink_policy: SymlinkPolicy,
34}
35
36impl ResolvedListOptions {
37 /// Creates this value inside the facade boundary.
38 ///
39 /// # Parameters
40 /// - `options`: Validated caller options after normalization.
41 /// - `symlink_policy`: Effective provider policy for this request.
42 #[inline]
43 pub(crate) const fn new(options: ListOptions, symlink_policy: SymlinkPolicy) -> Self {
44 Self {
45 options,
46 symlink_policy,
47 }
48 }
49
50 /// Returns the resolved options.
51 #[inline]
52 #[must_use]
53 pub const fn options(&self) -> &ListOptions {
54 &self.options
55 }
56
57 /// Returns the effective symbolic-link policy.
58 #[inline]
59 #[must_use = "the resolved symbolic-link policy must be used"]
60 pub const fn symlink_policy(&self) -> SymlinkPolicy {
61 self.symlink_policy
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use std::hint::black_box;
68
69 use super::ResolvedListOptions;
70 use crate::directory::ListOptions;
71 use crate::metadata::SymlinkPolicy;
72
73 #[test]
74 fn resolved_options_expose_their_values() {
75 let options = ListOptions::default().with_recursive(true);
76 let resolved = ResolvedListOptions::new(options.clone(), SymlinkPolicy::FollowWithinFileSystem);
77 let options_accessor: fn(&ResolvedListOptions) -> &ListOptions = black_box(ResolvedListOptions::options);
78 let policy_accessor: fn(&ResolvedListOptions) -> SymlinkPolicy = black_box(ResolvedListOptions::symlink_policy);
79
80 assert_eq!(&options, options_accessor(&resolved));
81 assert_eq!(SymlinkPolicy::FollowWithinFileSystem, policy_accessor(&resolved));
82 }
83}