use std::collections::HashMap; use miette::{IntoDiagnostic, Result}; use serde::Deserialize; use tokio::sync::RwLock; #[derive(Deserialize)] struct MiniDoc { handle: String, } pub struct Resolver { client: reqwest::Client, cache: RwLock>, } impl Resolver { pub fn new() -> Self { Self { client: reqwest::Client::new(), cache: RwLock::new(HashMap::new()), } } pub async fn resolve(&self, did: &str) -> Result { { let cache = self.cache.read().await; if let Some(handle) = cache.get(did) { return Ok(handle.clone()); } } let url = format!( "https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc?identifier={did}" ); let resp = self.client.get(&url).send().await.into_diagnostic()?; let mini_doc = resp.json::().await.into_diagnostic()?; self.cache .write() .await .insert(did.to_string(), mini_doc.handle.clone()); Ok(mini_doc.handle) } pub async fn cached(&self, did: &str) -> Option { self.cache.read().await.get(did).cloned() } pub async fn invalidate(&self, did: &str) { self.cache.write().await.remove(did); } }