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§
Sourcefn put(&self, key: &str, data: Vec<u8>) -> Result<(), Error>
fn put(&self, key: &str, data: Vec<u8>) -> Result<(), Error>
Write data at key. Overwrites any existing object unconditionally.
Sourcefn get(&self, key: &str) -> Result<Option<Vec<u8>>, Error>
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.).
Provided Methods§
Sourcefn head(&self, key: &str) -> Result<bool, Error>
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().
Sourcefn put_if(
&self,
_key: &str,
_data: Vec<u8>,
_cond: Precondition,
) -> Result<String, Error>
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.
Sourcefn etag(&self, _key: &str) -> Result<Option<String>, Error>
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".