Expand description
Sandboxed file I/O abstraction and implementation.
The SandboxedFs trait defines the I/O interface, and
FsSandbox provides the real filesystem implementation.
During testing, inject a mock implementation for I/O-free verification.
§Design
FsResolver / AssetResolver
|
v
Box<dyn SandboxedFs> <- Dependency inversion. Implementation is swappable
|
+---+---+
| |
FsSandbox CapSandbox (cap-std) MockSandbox (for testing)Rationale for using Box<dyn SandboxedFs> (dynamic dispatch):
Resolveritself usesVec<Box<dyn Resolver>>with dynamic dispatch- Making it generic would ultimately be converted to a trait object anyway, providing no benefit
- vtable overhead (~ns) is negligible compared to I/O (~us to ~ms)
§Error type separation
Construction-time and read-time errors are separated by type:
InitError– returned fromFsSandbox::new(). Root directory validation errors.ReadError– returned fromSandboxedFs::read(). Individual file access errors.
Rationale: construction failure is a configuration error (should be fixed at startup), while read failure is a runtime error (fallback or retry may be possible). This separation lets callers choose the appropriate recovery strategy.
§NotFound representation
File not found is returned as Ok(None) (not Err).
SandboxedFs::read() is a “search” operation where absence is a normal result.
This fits naturally with FsResolver’s candidate chain
({name}.lua -> {name}/init.lua).
Structs§
- File
Content - File read result.
- FsSandbox
- Real filesystem-based sandbox implementation.
Enums§
Traits§
- Sandboxed
Fs - Interface for sandboxed file reading.