pub trait WorkspaceFileSystemExt: Send + Sync {
// Required methods
fn read_text_with_version<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 WorkspacePath,
) -> Pin<Box<dyn Future<Output = WorkspaceResult<(String, String)>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn write_text_if_version<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
path: &'life1 WorkspacePath,
content: &'life2 str,
expected_version: &'life3 str,
) -> Pin<Box<dyn Future<Output = WorkspaceResult<WorkspaceWriteOutcome>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
}Expand description
Optional compare-and-swap extensions to WorkspaceFileSystem.
Implemented by backends that expose object-level versioning (S3 ETag,
future GCS generation, …) so tools that perform read-modify-write
cycles can reject concurrent overwrites. Tools should access this through
WorkspaceServices::fs_ext — when absent, callers fall back to plain
read_text / write_text (last-writer-wins).
Kept as a separate trait rather than inheriting from
WorkspaceFileSystem so existing backend implementations are not
forced to opt in.
Required Methods§
Sourcefn read_text_with_version<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 WorkspacePath,
) -> Pin<Box<dyn Future<Output = WorkspaceResult<(String, String)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_text_with_version<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 WorkspacePath,
) -> Pin<Box<dyn Future<Output = WorkspaceResult<(String, String)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Read text content together with an opaque version token. Tokens are backend-specific (S3 returns the ETag) and treated as opaque by callers — they are only ever compared for equality on the backend side.
Sourcefn write_text_if_version<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
path: &'life1 WorkspacePath,
content: &'life2 str,
expected_version: &'life3 str,
) -> Pin<Box<dyn Future<Output = WorkspaceResult<WorkspaceWriteOutcome>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn write_text_if_version<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
path: &'life1 WorkspacePath,
content: &'life2 str,
expected_version: &'life3 str,
) -> Pin<Box<dyn Future<Output = WorkspaceResult<WorkspaceWriteOutcome>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Write content iff the current object version matches expected_version.
On mismatch the returned error is the typed
WorkspaceError::VersionConflict variant; callers can also still
downcast through anyhow::Error when the value has been lifted into
the legacy result type.