Skip to main content

ObjectStore

Trait ObjectStore 

Source
pub trait ObjectStore: Send + Sync {
    // Required methods
    fn put(&self, key: &str, data: Vec<u8>) -> Result<(), Error>;
    fn get(&self, key: &str) -> Result<Option<Vec<u8>>, Error>;
    fn delete(&self, key: &str) -> Result<(), Error>;
    fn list_prefix(&self, prefix: &str) -> Result<Vec<String>, Error>;

    // Provided methods
    fn head(&self, key: &str) -> Result<bool, Error> { ... }
    fn put_if(
        &self,
        _key: &str,
        _data: Vec<u8>,
        _cond: Precondition,
    ) -> Result<String, Error> { ... }
    fn etag(&self, _key: &str) -> Result<Option<String>, Error> { ... }
}
Expand description

Minimal synchronous object-store surface.

Production impls connect to R2 / MinIO via AWS Sig V4. Tests inject InMemoryObjectStore so no network is required.

All methods are synchronous; async backends should block_on internally or expose a separate async trait alongside this one if the consumer is in a tokio context. (Scryer’s long-tier rollover runs on a blocking thread.)

Required Methods§

Source

fn put(&self, key: &str, data: Vec<u8>) -> Result<(), Error>

Write data at key. Overwrites any existing object unconditionally.

Source

fn get(&self, key: &str) -> Result<Option<Vec<u8>>, Error>

Read bytes at key. Returns None when the key does not exist — NotFound is reserved for ambiguous cases (HEAD-then-GET race etc.).

Source

fn delete(&self, key: &str) -> Result<(), Error>

Remove key. Idempotent — succeeds whether or not the key existed.

Source

fn list_prefix(&self, prefix: &str) -> Result<Vec<String>, Error>

List all keys with the given prefix (prefix-match, not glob).

Provided Methods§

Source

fn head(&self, key: &str) -> Result<bool, Error>

Returns true when key exists. Cheaper than get for backends that support HEAD; the default impl falls back to get(...).is_some().

Source

fn put_if( &self, _key: &str, _data: Vec<u8>, _cond: Precondition, ) -> Result<String, Error>

Conditionally write data at key, returning the resulting ETag.

An atomic compare-and-swap against cond. On a failed precondition the store is left untouched and Error::PreconditionFailed is returned — the caller re-reads (etag) and retries. The returned ETag is the comparand for the next Precondition::IfMatch in a CAS chain, so a single writer can advance a pointer without re-reading.

The default impl returns Error::Backend: a backend that cannot offer an atomic conditional write must not silently emulate it with get-then-put — that would break the linearizability callers depend on (W243’s cross-cell pointer fence). Backends that support it override this.

Source

fn etag(&self, _key: &str) -> Result<Option<String>, Error>

Current ETag of key, or None if absent.

The comparand a caller reads before a Precondition::IfMatch CAS. The default impl returns Error::Backend; backends supporting put_if override it.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§