pub trait KernelBackend: Send + Sync {
Show 22 methods
// Required methods
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
range: Option<ReadRange>,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
mode: WriteMode,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn append<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn patch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
ops: &'life2 [PatchOp],
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<DirEntry>, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn stat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<DirEntry, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn mkdir<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn set_mtime<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
mtime: SystemTime,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
recursive: bool,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn rename<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: &'life1 Path,
to: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn lstat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<DirEntry, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn read_link<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<PathBuf, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn symlink<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target: &'life1 Path,
link: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn call_tool<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: &'life1 str,
args: ToolArgs,
ctx: &'life2 mut dyn ToolCtx,
) -> Pin<Box<dyn Future<Output = Result<ToolResult, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
fn list_tools<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<ToolInfo>, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
fn get_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ToolInfo>, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn read_only(&self) -> bool;
fn backend_type(&self) -> &str;
fn mounts(&self) -> Vec<MountInfo>;
fn resolve_real_path(&self, path: &Path) -> Option<PathBuf>;
// Provided method
fn path_access<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<PathAccess, BackendError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait { ... }
}Expand description
Abstract backend interface for file operations and tool dispatch.
Implementations select where a path resolves and how tools are dispatched:
LocalBackend— VfsRouter-backed local filesystem (the default).KaijutsuBackend— CRDT-backed blocks when embedded in kaijutsu.
Required Methods§
Sourcefn read<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
range: Option<ReadRange>,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
range: Option<ReadRange>,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Read file contents, optionally with a range specification.
Sourcefn write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
mode: WriteMode,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
mode: WriteMode,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Write content to a file with the specified mode.
Sourcefn append<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn append<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Append content to a file.
Sourcefn patch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
ops: &'life2 [PatchOp],
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn patch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
ops: &'life2 [PatchOp],
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Apply a sequence of patch operations to a file.
Operations apply in order to one snapshot of the file, and the result
is written once. If an operation fails — a CAS expected mismatch, an
offset or line number past the end — the batch stops before the write
and the file keeps every byte it had. A caller holding an error never
has to work out how much of the batch survived.
The snapshot accumulates, so each operation sees the edits before it: offsets and line numbers are relative to the content as patched so far, not to the file as it was on entry. An insert at line 1 shifts the line numbers every later operation in the same batch uses.
The promise covers the operations, not the write that follows them.
Persisting the result is write’s business, with whatever crash,
concurrency, and I/O-error behavior the implementation gives it — a
write that fails partway through can still leave a partial file.
Sourcefn list<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<DirEntry>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<Vec<DirEntry>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
List a directory’s entries.
Sourcefn stat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<DirEntry, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn stat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<DirEntry, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Stat a path (following symlinks).
Sourcefn mkdir<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn mkdir<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Create a directory.
Sourcefn set_mtime<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
mtime: SystemTime,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn set_mtime<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
mtime: SystemTime,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Set the modification time of an existing path.
Read-only or purely-virtual mounts reject rather than silently
succeeding — touch on an existing file must route through here, never
escape to the host via resolve_real_path.
Sourcefn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
recursive: bool,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
recursive: bool,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Remove a file, directory, or symlink; recursive descends into a
directory. The final component is never followed: a symlink is
unlinked and its target kept, and a link to a directory is not
descended into.
Sourcefn rename<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: &'life1 Path,
to: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn rename<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: &'life1 Path,
to: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Rename/move a path. Neither side follows a final symlink: a symlink source moves as a link, and a symlink at the destination is replaced, never written through.
Sourcefn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Whether a path exists, following symlinks: a dangling link does not
exist, and an error reads as false. Use lstat to ask whether a
link is present.
Sourcefn lstat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<DirEntry, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn lstat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<DirEntry, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Stat a path without following symlinks.
Sourcefn read_link<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<PathBuf, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn read_link<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<PathBuf, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Read a symlink’s target as stored, without resolving it.
Sourcefn symlink<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target: &'life1 Path,
link: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn symlink<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target: &'life1 Path,
link: &'life2 Path,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Create a symlink at link pointing to target. The target is stored
verbatim; a relative target resolves from the link’s directory. An
absolute target is rewritten relative to the link when both are on one
mount, and refused when they are not.
Sourcefn call_tool<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: &'life1 str,
args: ToolArgs,
ctx: &'life2 mut dyn ToolCtx,
) -> Pin<Box<dyn Future<Output = Result<ToolResult, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn call_tool<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: &'life1 str,
args: ToolArgs,
ctx: &'life2 mut dyn ToolCtx,
) -> Pin<Box<dyn Future<Output = Result<ToolResult, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Call a tool by name with the given arguments and execution context.
For local backends, this executes the tool directly via ToolRegistry. For remote backends (e.g. kaijutsu), this may serialize the call and forward it to the parent process.
Sourcefn list_tools<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<ToolInfo>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn list_tools<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<ToolInfo>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
List available external tools.
Sourcefn get_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ToolInfo>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn get_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ToolInfo>, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Get information about a specific tool.
Sourcefn backend_type(&self) -> &str
fn backend_type(&self) -> &str
Returns the backend type identifier (e.g. “local”, “kaijutsu”).
Sourcefn resolve_real_path(&self, path: &Path) -> Option<PathBuf>
fn resolve_real_path(&self, path: &Path) -> Option<PathBuf>
Resolve a VFS path to a real filesystem path.
Returns Some(path) if the VFS path maps to a real filesystem (like
LocalFs), or None if the path is virtual (like MemoryFs). Tools like
git that hand paths to external C libraries need the real path.
Provided Methods§
Sourcefn path_access<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<PathAccess, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn path_access<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = Result<PathAccess, BackendError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
What the kernel can do with one path: the query behind test -r,
test -w, and test -x.
Neither KernelBackend::read_only nor DirEntry.permissions
answers “can this path be written” alone. A read-only wrapper over an
OS-writable directory reports permissive mode bits and refuses every
write; a DevFs mount reports read_only() == false (so > /dev/null works) while its /dev directory accepts nothing.
PathAccess::resolve combines the two, and is the only way to build
a PathAccess — a caller cannot consult one fact by accident.
The default answers from stat plus this backend’s whole-backend
read_only(), which is right for a backend that is uniformly
read-only or uniformly writable. A backend whose mounts differ —
LocalBackend, which routes through a VfsRouter — overrides this to
ask the mount that owns the path.
Errors exactly as stat does: a path that does not exist is an error,
not a PathAccess of all-false.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".