An ATProtocol powered blogging engine.
at main 2.3 kB view raw
1use atproto_identity::model::Document; 2use atproto_identity::resolve::IdentityResolver; 3use chrono::Utc; 4use std::sync::Arc; 5 6use crate::errors::Result; 7use crate::storage::{Identity, IdentityStorage}; 8 9/// A caching identity resolver that uses an underlying `IdentityStorage` implementation 10/// to cache resolved identity documents before falling back to the underlying `IdentityResolver`. 11pub struct CachingIdentityResolver<T: IdentityStorage + ?Sized> { 12 /// The underlying identity resolver to use when cache misses occur 13 resolver: IdentityResolver, 14 /// The storage implementation to use for caching 15 storage: Arc<T>, 16} 17 18impl<T: IdentityStorage + ?Sized> CachingIdentityResolver<T> { 19 /// Create a new caching identity resolver with the given resolver and storage. 20 pub fn new(resolver: IdentityResolver, storage: Arc<T>) -> Self { 21 Self { resolver, storage } 22 } 23 24 /// Resolve a DID to a Document, using the cache when possible. 25 pub async fn resolve(&self, did: &str) -> Result<Document> { 26 // First, try to get the identity from storage 27 if let Some(identity) = self.storage.get_identity_by_did(did).await? { 28 // Parse the stored record back to a Document 29 let document: Document = serde_json::from_value(identity.record)?; 30 return Ok(document); 31 } 32 33 // If not in storage, resolve using the underlying resolver 34 let document = self.resolver.resolve(did).await?; 35 36 // Store the resolved identity for future lookups 37 self.store_resolved_identity(&document).await?; 38 39 Ok(document) 40 } 41 42 /// Store a resolved identity document in the storage. 43 async fn store_resolved_identity(&self, doc: &Document) -> Result<()> { 44 let handle = doc 45 .also_known_as 46 .first() 47 .and_then(|aka| aka.strip_prefix("at://")) 48 .unwrap_or("unknown.handle") 49 .to_string(); 50 51 // Create a JSON representation of the document 52 let record = serde_json::json!(doc); 53 54 let identity = Identity { 55 did: doc.id.clone(), 56 handle, 57 record, 58 created_at: Utc::now(), 59 updated_at: Utc::now(), 60 }; 61 62 self.storage.upsert_identity(&identity).await?; 63 Ok(()) 64 } 65}