#![forbid(unsafe_code)]
use futures_core::Stream;
use std::any::{Any, TypeId};
use std::borrow::Cow;
use std::collections::HashMap;
use std::future::Future;
use std::hash::{BuildHasherDefault, Hasher};
use std::ops::DerefMut;
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct Scope {
protocol: Cow<'static, str>,
scopes: HashMap<TypeId, Arc<dyn Any + Sync + Send>, BuildHasherDefault<TypeIdHasher>>,
}
impl Scope {
#[inline]
pub fn new(protocol: Cow<'static, str>) -> Self {
Self {
protocol,
scopes: Default::default(),
}
}
#[inline]
pub fn protocol(&self) -> &str {
&self.protocol
}
#[inline]
pub fn with_protocol(self, protocol: Cow<'static, str>) -> Self {
Self {
protocol,
scopes: self.scopes,
}
}
#[inline]
pub fn get<T: Any + Sync + Send>(&self) -> Option<Arc<T>> {
self.scopes
.get(&TypeId::of::<T>())?
.clone()
.downcast::<T>()
.ok()
}
#[inline]
pub fn get_ref<T: Any + Sync + Send>(&self) -> Option<&T> {
self.scopes.get(&TypeId::of::<T>())?.downcast_ref::<T>()
}
#[inline]
pub fn insert<T: Any + Sync + Send>(&mut self, scope: T) -> Option<Arc<T>> {
self.scopes
.insert(TypeId::of::<T>(), Arc::new(scope))
.map(|arc| arc.downcast::<T>().unwrap())
}
#[inline]
pub fn remove<T: Any + Sync + Send>(&mut self) -> Option<Arc<T>> {
self.scopes
.remove(&TypeId::of::<T>())
.map(|arc| arc.downcast::<T>().unwrap())
}
#[inline]
pub fn with_scope<T: Any + Sync + Send>(mut self, scope: T) -> Self {
let _ = self.insert(scope);
self
}
}
#[derive(Clone, Debug)]
pub struct Event {
family: Cow<'static, str>,
event: Arc<dyn Any + Sync + Send>,
}
impl Event {
#[inline]
pub fn new<T: Any + Sync + Send>(family: Cow<'static, str>, event: T) -> Self {
Self {
family,
event: Arc::new(event),
}
}
#[inline]
pub fn family(&self) -> &str {
&self.family
}
#[inline]
pub fn get<T: Any + Sync + Send>(&self) -> Option<Arc<T>> {
self.event.clone().downcast::<T>().ok()
}
#[inline]
pub fn get_ref<T: Any + Sync + Send>(&self) -> Option<&T> {
self.event.downcast_ref::<T>()
}
}
pub trait Service<ServerStream: Stream<Item = Event>> {
type AppStream: Stream<Item = Event>;
type Error: std::error::Error;
type Future: Future<Output = Result<Self::AppStream, Self::Error>>;
fn call(&mut self, scope: Scope, server_events: ServerStream) -> Self::Future;
}
#[derive(Default)]
struct TypeIdHasher {
value: u64,
}
impl Hasher for TypeIdHasher {
#[inline]
fn finish(&self) -> u64 {
self.value
}
#[inline]
fn write(&mut self, bytes: &[u8]) {
debug_assert_eq!(bytes.len(), 8);
let _ = bytes
.try_into()
.map(|array| self.value = u64::from_ne_bytes(array));
}
}
impl<X, S, SS> Service<SS> for X
where
X: DerefMut<Target = S>,
S: Service<SS>,
SS: Stream<Item = Event>,
{
type AppStream = S::AppStream;
type Error = S::Error;
type Future = S::Future;
fn call(&mut self, scope: Scope, server_events: SS) -> Self::Future {
(**self).call(scope, server_events)
}
}