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§
Sourcefn 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 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.
Sourcefn 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 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)
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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,
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".