use std::any::type_name;
use std::fmt::Debug;
use std::ops::Deref;
use std::ops::DerefMut;
use crate::error;
use crate::map::AnyMap;
use crate::map::Entry;
use crate::map::ErasedTy;
use crate::Error;
pub trait AppStorage {
fn set_app_data<T: ErasedTy>(&mut self, val: T) -> Option<T>;
fn app_data<T: ErasedTy>(&self) -> Result<&T, Error>;
fn app_data_mut<T: ErasedTy>(&mut self) -> Result<&mut T, Error>;
fn take_app_data<T: ErasedTy>(&mut self) -> Result<T, Error>;
}
#[derive(Debug, Default)]
pub struct AppServices(UsrValService);
impl AppServices {
pub fn new() -> Self {
Self {
..Default::default()
}
}
}
impl AppStorage for AppServices {
fn set_app_data<T: ErasedTy>(&mut self, val: T) -> Option<T> {
self.0.insert(val)
}
fn app_data<T: ErasedTy>(&self) -> Result<&T, Error> {
self.0.val::<T>()
}
fn app_data_mut<T: ErasedTy>(&mut self) -> Result<&mut T, Error> {
self.0.val_mut::<T>()
}
fn take_app_data<T: ErasedTy>(&mut self) -> Result<T, Error> {
self.0.remove::<T>().ok_or_else(|| {
error!(
"can not take value type `{}` from AppServices",
type_name::<T>()
)
})
}
}
impl Deref for AppServices {
type Target = UsrValService;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for AppServices {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Default)]
pub struct UsrValService(AnyMap);
impl Debug for UsrValService {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("UsrValService").field(&self.0).finish()
}
}
impl UsrValService {
pub fn new() -> Self {
Self(AnyMap::default())
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn clear(&mut self) {
self.0.clear()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn contain_type<T: ErasedTy>(&self) -> bool {
self.0.contain::<T>()
}
pub fn insert<T: ErasedTy>(&mut self, value: T) -> Option<T> {
self.0.insert(value)
}
pub fn remove<T: ErasedTy>(&mut self) -> Option<T> {
self.0.remove::<T>()
}
pub fn get<T: ErasedTy>(&self) -> Option<&T> {
self.0.value::<T>()
}
pub fn get_mut<T: ErasedTy>(&mut self) -> Option<&mut T> {
self.0.value_mut::<T>()
}
pub fn val<T: ErasedTy>(&self) -> Result<&T, Error> {
self.get::<T>().ok_or_else(|| {
error!(
"can not find reference for type `{:?}` in UsrValService",
type_name::<T>()
)
})
}
pub fn val_mut<T: ErasedTy>(&mut self) -> Result<&mut T, Error> {
self.get_mut::<T>().ok_or_else(|| {
error!(
"can not find reference(mut) for type `{:?}` in UsrValService",
type_name::<T>()
)
})
}
pub fn entry<T: ErasedTy>(&mut self) -> Entry<'_, T> {
self.0.entry::<T>()
}
}