pub mod eds; pub use eds::EDSContactResolverBackend; use std::collections::HashMap; pub trait ContactResolverBackend { type ContactID; fn resolve_contact_id(&self, address: &str) -> Option; fn get_contact_display_name(&self, contact_id: &Self::ContactID) -> Option; } pub type AnyContactID = String; #[derive(Clone)] pub struct ContactResolver { backend: T, display_name_cache: HashMap, contact_id_cache: HashMap, } impl ContactResolver where T::ContactID: From, T::ContactID: Into, T: Default, { pub fn new(backend: T) -> Self { Self { backend, display_name_cache: HashMap::new(), contact_id_cache: HashMap::new() } } pub fn resolve_contact_id(&mut self, address: &str) -> Option { if let Some(id) = self.contact_id_cache.get(address) { return Some(id.clone()); } let id = self.backend.resolve_contact_id(address).map(|id| id.into()); if let Some(ref id) = id { self.contact_id_cache.insert(address.to_string(), id.clone()); } id } pub fn get_contact_display_name(&mut self, contact_id: &AnyContactID) -> Option { if let Some(display_name) = self.display_name_cache.get(contact_id) { return Some(display_name.clone()); } let backend_contact_id: T::ContactID = T::ContactID::from((*contact_id).clone()); let display_name = self.backend.get_contact_display_name(&backend_contact_id); if let Some(ref display_name) = display_name { self.display_name_cache.insert(contact_id.to_string(), display_name.clone()); } display_name } } impl Default for ContactResolver where T::ContactID: From, T::ContactID: Into, T: Default, { fn default() -> Self { Self::new(T::default()) } }