Skip to main content

StorageAdapter

Trait StorageAdapter 

Source
pub trait StorageAdapter:
    Debug
    + Send
    + Sync {
    // Required methods
    fn read_text<'life0, 'life1, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn write_text<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
        contents: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn write_text_if_absent<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
        contents: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn exists<'life0, 'life1, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn rename_text<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        from_uri: &'life1 str,
        to_uri: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn delete<'life0, 'life1, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn list_dir<'life0, 'life1, 'async_trait>(
        &'life0 self,
        dir_uri: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<String>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn read_text_versioned<'life0, 'life1, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<(String, String)>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn write_text_if_match<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        uri: &'life1 str,
        contents: &'life2 str,
        expected_version: &'life3 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait;
    fn delete_prefix<'life0, 'life1, 'async_trait>(
        &'life0 self,
        prefix_uri: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}

Required Methods§

Source

fn read_text<'life0, 'life1, 'async_trait>( &'life0 self, uri: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source

fn write_text<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, uri: &'life1 str, contents: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source

fn write_text_if_absent<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, uri: &'life1 str, contents: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Write a text object only if no object exists at uri.

Returns Ok(true) when this call created the object, Ok(false) when the object already existed, and propagates every other storage error. Callers use this to establish ownership before running best-effort cleanup on partial failure.

Source

fn exists<'life0, 'life1, 'async_trait>( &'life0 self, uri: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source

fn rename_text<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, from_uri: &'life1 str, to_uri: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Move a file from from_uri to to_uri, replacing any existing file at to_uri. Atomic on local POSIX; on S3 implemented as copy + delete (NOT atomic — callers that depend on atomicity for crash recovery must tolerate “both source and destination exist after a crash”).

Source

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, uri: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Remove a file. Returns Ok(()) if the file does not exist.

Source

fn list_dir<'life0, 'life1, 'async_trait>( &'life0 self, dir_uri: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List all files (non-recursively, files only) directly under dir_uri. Returns full URIs (same scheme as dir_uri). The result is unordered. Returns Ok(empty) if the directory does not exist or is empty. Consumers must tolerate non-payload residue appearing in storage (backend staging files are filtered by the backend, but crash residue of any future producer may not be) — filter by suffix, never assume every entry is yours.

Source

fn read_text_versioned<'life0, 'life1, 'async_trait>( &'life0 self, uri: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(String, String)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Read a text object together with its backend version token (stores with conditional-update support: the object’s ETag; local: sha256 of the content). The token is opaque — valid only for write_text_if_match against the same adapter.

Source

fn write_text_if_match<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, uri: &'life1 str, contents: &'life2 str, expected_version: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Replace the object at uri only if its current version still matches expected_version (obtained from a prior versioned read/write on this adapter). Returns Ok(Some(new_version)) on success and Ok(None) when the precondition failed (a concurrent writer won — the CAS-lost case callers must surface, never swallow). Stores with conditional updates (S3, in-memory) use a true conditional put (If-Match); the local filesystem has no such primitive (PutMode::Update is unimplemented upstream), so local compares content then replaces via an atomic staged write — the same single-machine semantics the callers had before this trait, safe under the callers’ own lock protocol but not a cross-process barrier by itself (see the Known Gaps entry in docs/dev/invariants.md).

Source

fn delete_prefix<'life0, 'life1, 'async_trait>( &'life0 self, prefix_uri: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Recursively delete every object under prefix_uri. Returns Ok(()) when nothing exists there (idempotent). Local: remove_dir_all (directories are a local-FS concept; list+delete would leave empty directory skeletons that local existence probes report as present); object stores: list + delete (NOT atomic — callers must tolerate partial prefixes on crash, which the cluster delete protocol does by retry).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§