use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::fmt;
use std::net::SocketAddr; use std::sync::Arc;
#[derive(Default, Clone)]
pub struct Metadata {
inner: Arc<tokio::sync::RwLock<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>>,
}
impl Metadata {
pub fn new() -> Self {
Self::default()
}
pub async fn insert_typed<T: Any + Send + Sync>(
&self, value: T,
) -> Option<Arc<dyn Any + Send + Sync>> {
let mut map = self.inner.write().await; map.insert(TypeId::of::<T>(), Arc::new(value))
}
pub async fn get<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
let map = self.inner.read().await; map.get(&TypeId::of::<T>()).and_then(|arc_any| {
arc_any.clone().downcast::<T>().ok()
})
}
pub async fn contains<T: Any + Send + Sync>(&self) -> bool {
let map = self.inner.read().await;
map.contains_key(&TypeId::of::<T>())
}
pub async fn remove<T: Any + Send + Sync>(&self) -> Option<Arc<dyn Any + Send + Sync>> {
let mut map = self.inner.write().await;
map.remove(&TypeId::of::<T>())
}
pub async fn is_empty(&self) -> bool {
self.inner.read().await.is_empty()
}
pub async fn len(&self) -> usize {
self.inner.read().await.len()
}
}
impl fmt::Debug for Metadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Metadata").finish_non_exhaustive()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PeerAddress(pub SocketAddr);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ZapUserId(pub String);