Skip to main content

Storage

Trait Storage 

Source
pub trait Storage:
    Send
    + Sync
    + Debug {
Show 31 methods // Required methods fn list_providers<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<Provider>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn get_provider<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Provider>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_models<'life0, 'life1, 'async_trait>( &'life0 self, provider_id: Option<&'life1 str>, ) -> Pin<Box<dyn Future<Output = Result<Vec<Model>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn get_model<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Model>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_channels<'life0, 'life1, 'async_trait>( &'life0 self, model_id: Option<&'life1 str>, ) -> Pin<Box<dyn Future<Output = Result<Vec<Channel>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn get_channel<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Channel>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn upsert_channel<'life0, 'life1, 'async_trait>( &'life0 self, channel: &'life1 Channel, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn set_channel_enabled<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, enabled: bool, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn set_channel_api_key<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, key: &'life2 SecretString, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn update_channel<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, id: &'life1 str, name: Option<&'life2 str>, enabled: Option<bool>, priority: Option<u32>, monthly_quota: Option<u64>, quota_policy: Option<&'life3 str>, protocols: Option<&'life4 str>, force_protocol: Option<&'life5 str>, ) -> Pin<Box<dyn Future<Output = Result<Channel, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait; fn delete_channel<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn mark_channel_healthy<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn record_channel_failure<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_mappings<'life0, 'life1, 'async_trait>( &'life0 self, channel_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<ModelMapping>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn upsert_mapping<'life0, 'life1, 'async_trait>( &'life0 self, mapping: &'life1 ModelMapping, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn set_mapping_enabled<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, enabled: bool, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn delete_mapping<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_all_mappings<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<ModelMapping>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn insert_cost_record<'life0, 'life1, 'async_trait>( &'life0 self, record: &'life1 CostRecord, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn query_cost_records<'life0, 'async_trait>( &'life0 self, filter: CostFilter, ) -> Pin<Box<dyn Future<Output = Result<Vec<CostRecord>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn aggregate_costs<'life0, 'async_trait>( &'life0 self, group_by: CostGroupBy, range: TimeRange, ) -> Pin<Box<dyn Future<Output = Result<Vec<CostAggregate>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn prune_cost_records<'life0, 'async_trait>( &'life0 self, older_than_days: u32, ) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn list_projects<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn insert_switch_log<'life0, 'life1, 'async_trait>( &'life0 self, log: &'life1 SwitchLog, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn query_switch_logs<'life0, 'async_trait>( &'life0 self, limit: Option<u32>, ) -> Pin<Box<dyn Future<Output = Result<Vec<SwitchLog>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn list_available_channels<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<AvailableChannelInfo>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn insert_subscription_fee<'life0, 'life1, 'async_trait>( &'life0 self, fee: &'life1 SubscriptionFee, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn query_subscription_fees<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, channel: Option<&'life1 str>, month: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<Vec<SubscriptionFee>, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn migrate<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn health_check<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn max_connections(&self) -> usize;
}
Expand description

Backend-agnostic storage for providers, models, channels, and cost records.

Every method except max_connections is async and returns Result<T, StorageError>. Implementations must be Send + Sync so the trait object can be shared across Tokio tasks behind an Arc.

Required Methods§

Source

fn list_providers<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<Provider>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

List all providers.

Source

fn get_provider<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Provider>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get a single provider by ID.

Source

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

List models, optionally filtered by provider.

Source

fn get_model<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Model>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get a single model by ID.

Source

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

List all channels, optionally filtered by model ID.

Source

fn get_channel<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Channel>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get a single channel by ID.

Source

fn upsert_channel<'life0, 'life1, 'async_trait>( &'life0 self, channel: &'life1 Channel, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Insert or replace a channel (upsert).

Source

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

Toggle a channel enabled/disabled.

Source

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

Update just the API key for a channel.

Source

fn update_channel<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, id: &'life1 str, name: Option<&'life2 str>, enabled: Option<bool>, priority: Option<u32>, monthly_quota: Option<u64>, quota_policy: Option<&'life3 str>, protocols: Option<&'life4 str>, force_protocol: Option<&'life5 str>, ) -> Pin<Box<dyn Future<Output = Result<Channel, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait,

Update channel fields (name, enabled, priority, quota, protocols, force_protocol).

Source

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

Delete a channel and its model mappings (cascade).

Source

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

Mark a channel as healthy (reset failures).

Source

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

Record a channel failure (increments counter, may set Degraded/Cooldown).

Source

fn list_mappings<'life0, 'life1, 'async_trait>( &'life0 self, channel_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<ModelMapping>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List all model mappings for a channel.

Source

fn upsert_mapping<'life0, 'life1, 'async_trait>( &'life0 self, mapping: &'life1 ModelMapping, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Upsert a single model mapping.

Source

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

Toggle a model mapping enabled/disabled.

Source

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

Delete a model mapping.

Source

fn list_all_mappings<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<ModelMapping>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

List all model mappings.

Source

fn insert_cost_record<'life0, 'life1, 'async_trait>( &'life0 self, record: &'life1 CostRecord, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Record a completed request.

Source

fn query_cost_records<'life0, 'async_trait>( &'life0 self, filter: CostFilter, ) -> Pin<Box<dyn Future<Output = Result<Vec<CostRecord>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Query cost records with optional filters.

Source

fn aggregate_costs<'life0, 'async_trait>( &'life0 self, group_by: CostGroupBy, range: TimeRange, ) -> Pin<Box<dyn Future<Output = Result<Vec<CostAggregate>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Aggregate costs grouped by the given dimension within a time range.

Source

fn prune_cost_records<'life0, 'async_trait>( &'life0 self, older_than_days: u32, ) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete records older than N days, returning the count of deleted rows.

Source

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

List distinct project paths from cost records, sorted alphabetically.

Source

fn insert_switch_log<'life0, 'life1, 'async_trait>( &'life0 self, log: &'life1 SwitchLog, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Record a channel switch event.

Source

fn query_switch_logs<'life0, 'async_trait>( &'life0 self, limit: Option<u32>, ) -> Pin<Box<dyn Future<Output = Result<Vec<SwitchLog>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Query recent switch logs, optionally limited.

Source

fn list_available_channels<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<AvailableChannelInfo>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

List all enabled channels with their bound models. Used by token-fleet-switch for Claude direct-connect mode.

Source

fn insert_subscription_fee<'life0, 'life1, 'async_trait>( &'life0 self, fee: &'life1 SubscriptionFee, ) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Record a monthly subscription fee.

Source

fn query_subscription_fees<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, channel: Option<&'life1 str>, month: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<Vec<SubscriptionFee>, StorageError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Query subscription fees optionally filtered by channel and/or month.

Source

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

Run migrations / schema init. Idempotent — safe to call on every startup.

Source

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

Health check — returns true if the backend is reachable.

Source

fn max_connections(&self) -> usize

Maximum number of concurrent connections this backend supports.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§