Skip to main content

Kv

Trait Kv 

Source
pub trait Kv: Binding {
    // Required methods
    fn get<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn put<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
        value: Vec<u8>,
        options: Option<PutOptions>,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn delete<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn exists<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn scan_prefix<'life0, 'life1, 'async_trait>(
        &'life0 self,
        prefix: &'life1 str,
        limit: Option<usize>,
        cursor: Option<String>,
    ) -> Pin<Box<dyn Future<Output = Result<ScanResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

A trait for key-value store bindings that provide minimal, platform-agnostic KV operations. This API is designed to work consistently across DynamoDB, Firestore, Redis, and Azure Table Storage.

Required Methods§

Source

fn get<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get a value by key. Returns None if key doesn’t exist or has expired.

TTL Behavior: TTL is a soft hint for automatic cleanup. If now >= expires_at, implementations SHOULD behave as if the key is absent, even if the item still exists physically in the backend. Physical deletion is eventual and not guaranteed.

Validation: Keys are validated against MAX_KEY_BYTES and portable charset. Invalid keys return KvError::InvalidKey immediately.

Source

fn put<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, value: Vec<u8>, options: Option<PutOptions>, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Put a value with optional options. When options.if_not_exists is true, returns true if created, false if already exists. When options.if_not_exists is false or options is None, always returns true.

Size Limits:

  • Keys: ≤ MAX_KEY_BYTES (512 bytes) with portable ASCII charset
  • Values: ≤ MAX_VALUE_BYTES (24,576 bytes = 24 KiB)

Validation: Size and charset constraints are enforced before backend calls. Invalid inputs return KvError::InvalidKey or KvError::InvalidValue immediately.

TTL Behavior: TTL is a soft hint for automatic cleanup. If TTL is specified, item expires at put_time + ttl. Expired items SHOULD appear absent on subsequent reads, but physical deletion is eventual and not guaranteed.

Conditional Logic: The if_not_exists operation maps to backend primitives:

  • Redis: SETNX
  • DynamoDB: PutItem with condition_expression=“attribute_not_exists(pk)”
  • Firestore: create() with Precondition::DoesNotExist
  • Azure Table Storage: InsertEntity (409 on conflict)
Source

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

Delete a key. No error if key doesn’t exist.

Validation: Keys are validated against MAX_KEY_BYTES and portable charset. Invalid keys return KvError::InvalidKey immediately.

Source

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

Check if a key exists without retrieving the value.

TTL Behavior: TTL is a soft hint for automatic cleanup. If now >= expires_at, SHOULD return false even if physically present. Physical deletion is eventual and not guaranteed.

Validation: Keys are validated against MAX_KEY_BYTES and portable charset. Invalid keys return KvError::InvalidKey immediately.

Source

fn scan_prefix<'life0, 'life1, 'async_trait>( &'life0 self, prefix: &'life1 str, limit: Option<usize>, cursor: Option<String>, ) -> Pin<Box<dyn Future<Output = Result<ScanResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Scan keys with a prefix, with pagination support.

Scan Contract:

  • Returns an arbitrary, unordered subset in backend-natural order
  • No ordering guarantees across backends (Redis SCAN, Azure fan-out, etc.)
  • May return ≤ limit items (not guaranteed to fill even if more data exists)
  • Clients MUST de-duplicate keys across pages (backends may return duplicates)
  • No completeness guarantee under concurrent writes (may miss or duplicate)

Cursor Behavior:

  • Opaque string, implementation-specific format
  • May become invalid anytime after backend state changes
  • No TTL guarantees - can expire without notice
  • Passing invalid cursor should return error, not partial results

TTL Behavior: TTL is a soft hint for automatic cleanup. Expired items SHOULD be filtered out from results, but physical deletion is eventual and not guaranteed.

Validation: Prefix follows same key validation rules. Invalid prefix returns KvError::InvalidKey immediately.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§