use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use dashmap::DashMap;
use super::resolver::{KeyResolver, KeyResolverError, ResolvedKey};
pub struct InMemoryKeyResolver {
keys: Arc<DashMap<String, ResolvedKey>>,
}
impl InMemoryKeyResolver {
#[must_use]
pub fn new() -> Self {
Self {
keys: Arc::new(DashMap::new()),
}
}
#[must_use]
pub fn with_entries(entries: impl IntoIterator<Item = (String, ResolvedKey)>) -> Self {
let keys = DashMap::new();
for (k, v) in entries {
keys.insert(k, v);
}
Self { keys: Arc::new(keys) }
}
pub fn insert(&self, api_key: impl Into<String>, resolved: ResolvedKey) {
self.keys.insert(api_key.into(), resolved);
}
pub fn remove(&self, api_key: &str) -> Option<ResolvedKey> {
self.keys.remove(api_key).map(|(_, v)| v)
}
}
impl Default for InMemoryKeyResolver {
fn default() -> Self {
Self::new()
}
}
impl KeyResolver for InMemoryKeyResolver {
fn resolve(
&self,
api_key: String,
) -> Pin<Box<dyn Future<Output = Result<ResolvedKey, KeyResolverError>> + Send + 'static>> {
let keys = self.keys.clone();
Box::pin(async move {
match keys.get(&api_key) {
None => Err(KeyResolverError::NotFound),
Some(entry) => {
if !entry.active {
Err(KeyResolverError::Inactive)
} else {
Ok(entry.clone())
}
}
}
})
}
}