#![warn(clippy::all, clippy::perf, clippy::style, clippy::suspicious)] #[cfg(feature = "postgres")] pub mod postgres; pub mod local; pub mod send; use std::sync::Arc; use async_trait::async_trait; use thiserror::Error; use torn_api::ResponseError; #[derive(Debug, Error)] pub enum KeyPoolError where S: std::error::Error, C: std::error::Error, { #[error("Key pool storage driver error: {0:?}")] Storage(#[source] Arc), #[error(transparent)] Client(#[from] C), #[error(transparent)] Response(ResponseError), } pub trait ApiKey: Sync + Send { type IdType: PartialEq + Eq + std::hash::Hash; fn value(&self) -> &str; fn id(&self) -> Self::IdType; } pub trait KeyDomain: Clone + std::fmt::Debug + Send + Sync { fn fallback(&self) -> Option { None } } #[derive(Debug, Clone)] pub enum KeySelector where K: ApiKey, { Key(String), Id(K::IdType), } #[async_trait] pub trait KeyPoolStorage { type Key: ApiKey; type Domain: KeyDomain; type Error: std::error::Error + Sync + Send; async fn acquire_key(&self, domain: Self::Domain) -> Result; async fn acquire_many_keys( &self, domain: Self::Domain, number: i64, ) -> Result, Self::Error>; async fn flag_key(&self, key: Self::Key, code: u8) -> Result; async fn store_key( &self, user_id: i32, key: String, domains: Vec, ) -> Result; async fn read_key(&self, key: KeySelector) -> Result, Self::Error>; async fn read_user_keys(&self, user_id: i32) -> Result, Self::Error>; async fn remove_key(&self, key: KeySelector) -> Result; async fn query_key(&self, domain: Self::Domain) -> Result, Self::Error>; async fn query_all(&self, domain: Self::Domain) -> Result, Self::Error>; async fn add_domain_to_key( &self, key: KeySelector, domain: Self::Domain, ) -> Result; async fn remove_domain_from_key( &self, key: KeySelector, domain: Self::Domain, ) -> Result; async fn set_domains_for_key( &self, key: KeySelector, domains: Vec, ) -> Result; } #[derive(Debug, Clone)] pub struct KeyPoolExecutor<'a, C, S> where S: KeyPoolStorage, { storage: &'a S, comment: Option<&'a str>, domain: S::Domain, _marker: std::marker::PhantomData, } impl<'a, C, S> KeyPoolExecutor<'a, C, S> where S: KeyPoolStorage, { pub fn new(storage: &'a S, domain: S::Domain, comment: Option<&'a str>) -> Self { Self { storage, domain, comment, _marker: std::marker::PhantomData, } } } #[cfg(all(test, feature = "postgres"))] mod test {}