pub trait WorkspaceStoreAdapter: Send + Sync {
// Required methods
fn load(&self, workspace_root: &Path) -> Result<Workspace, StoreError>;
fn save_state(
&self,
workspace_root: &Path,
workspace: &Workspace,
) -> Result<(), StoreError>;
fn read_state_bytes(
&self,
workspace_root: &Path,
) -> Result<Option<Vec<u8>>, StoreError>;
fn parse_state_bytes(
&self,
workspace_root: &Path,
bytes: &[u8],
) -> Result<Vec<Mount>, StoreError>;
fn save_state_cas(
&self,
workspace_root: &Path,
workspace: &Workspace,
expected: Option<&[u8]>,
) -> Result<bool, StoreError>;
}Expand description
Adapter trait — the seam between the engine and the persisted
workspace state. Implementations decide where the mount list
lives (two files under .memstead/, a SQLite database, a remote
service, an in-memory test fixture); the engine consumes the
produced Workspace uniformly.
Required Methods§
Sourcefn load(&self, workspace_root: &Path) -> Result<Workspace, StoreError>
fn load(&self, workspace_root: &Path) -> Result<Workspace, StoreError>
Load the workspace from workspace_root. Implementations
resolve the adapter-specific files relative to this root
(e.g. the file adapter reads
<workspace_root>/.memstead/workspace.toml +
<workspace_root>/.memstead/state/mounts.json).
Sourcefn save_state(
&self,
workspace_root: &Path,
workspace: &Workspace,
) -> Result<(), StoreError>
fn save_state( &self, workspace_root: &Path, workspace: &Workspace, ) -> Result<(), StoreError>
Persist the engine-managed slice of state (today: the mount
list). Operator-edited fields stay untouched — adapters that
share one file with operator content must not overwrite it
here. The two-layer file adapter writes only
state/mounts.json.
Last-writer-wins. Prefer Self::save_state_cas whenever the
caller can name what it read: a long-lived process that dumps
its cached roster over this call drops every mount a sibling
process registered since the dump was taken.
Sourcefn read_state_bytes(
&self,
workspace_root: &Path,
) -> Result<Option<Vec<u8>>, StoreError>
fn read_state_bytes( &self, workspace_root: &Path, ) -> Result<Option<Vec<u8>>, StoreError>
Raw bytes of the engine-managed state file, or None when it
does not exist yet. The compare token for
Self::save_state_cas.
Sourcefn parse_state_bytes(
&self,
workspace_root: &Path,
bytes: &[u8],
) -> Result<Vec<Mount>, StoreError>
fn parse_state_bytes( &self, workspace_root: &Path, bytes: &[u8], ) -> Result<Vec<Mount>, StoreError>
Parse state bytes previously returned by
Self::read_state_bytes into the mount roster they carry.
Sourcefn save_state_cas(
&self,
workspace_root: &Path,
workspace: &Workspace,
expected: Option<&[u8]>,
) -> Result<bool, StoreError>
fn save_state_cas( &self, workspace_root: &Path, workspace: &Workspace, expected: Option<&[u8]>, ) -> Result<bool, StoreError>
Compare-and-set counterpart of Self::save_state: write only
when the on-disk state still equals expected, and report a
mismatch as Ok(false) rather than an error so the caller can
re-read, re-merge and retry. The check and the write are one
step under the adapter’s own lock — a caller that reads, then
compares, then writes leaves exactly the window this exists to
close.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".