#![deny(missing_docs, unused, warnings)]
mod entry;
mod stable_type_id;
mod write_guard;
use crate::entry::{Entry, OccupiedEntry, OccupiedError, VacantEntry};
use crate::write_guard::WriteGuard;
use serde::{Deserialize, Serialize};
use serde_value::{Value, to_value};
pub use stable_type_id::StableTypeId;
use std::collections::{TryReserveError, hash_map};
use std::marker::PhantomData;
use std::{any::Any, collections::HashMap};
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
#[serde(transparent)]
pub struct SerializableAnyMap {
raw: HashMap<StableTypeId, RawItem>,
}
impl SerializableAnyMap {
#[inline]
pub fn new() -> Self {
Self {
raw: HashMap::new(),
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
raw: HashMap::with_capacity(capacity),
}
}
#[inline]
pub fn capacity(&self) -> usize {
self.raw.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.raw.reserve(additional);
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.raw.try_reserve(additional)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.raw.shrink_to_fit()
}
#[inline]
pub fn shrink_to(&mut self, min_capcity: usize) {
self.raw.shrink_to(min_capcity)
}
#[inline]
pub fn len(&self) -> usize {
self.raw.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.raw.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.raw.clear()
}
#[inline]
pub fn try_get<T>(&self) -> Option<&T>
where
T: for<'de> Deserialize<'de> + Any + 'static,
{
let key = StableTypeId::for_type::<T>();
self.raw.get(&key)?.try_get()
}
#[inline]
pub fn get<T>(&mut self) -> Option<Result<&T, serde_value::DeserializerError>>
where
T: Serialize + for<'de> Deserialize<'de> + 'static,
{
match self.entry::<T>() {
(Entry::Occupied(inner), None) => Some(inner.into_mut().map(|g| g.into_ref())),
(Entry::Vacant(_), None) => None,
(_, Some(e)) => Some(Err(e)),
}
}
#[inline]
pub fn get_deserialized_copy<T>(&self) -> Option<T>
where
T: for<'de> Deserialize<'de> + Any + 'static,
{
self.get_serialized_value::<T>()
.and_then(|v| T::deserialize(v.clone()).ok())
}
pub fn get_mut<T>(
&mut self,
) -> Option<Result<WriteGuard<'_, T>, serde_value::DeserializerError>>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
match self.entry::<T>() {
(Entry::Occupied(inner), None) => Some(inner.into_mut()),
(Entry::Vacant(_), None) => None,
(_, Some(e)) => Some(Err(e)),
}
}
#[inline]
pub fn get_serialized_value<T>(&self) -> Option<&Value>
where
T: 'static,
{
let key = StableTypeId::for_type::<T>();
self.raw.get(&key).map(|e| &e.serialized)
}
#[inline]
pub fn insert_only_serialized<T>(&mut self, value: Value) -> Option<Item<T>> {
let key = StableTypeId::for_type::<T>();
let e = RawItem {
serialized: value,
value: None,
};
self.raw.insert(key, e).map(RawItem::wrap)
}
#[inline]
pub fn insert<T>(&mut self, value: T) -> Option<Item<T>>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
let key = StableTypeId::for_type::<T>();
let serialized = to_value(&value).expect("serialization failed");
let new_entry = RawItem {
serialized,
value: Some(Box::new(value)),
};
self.raw.insert(key, new_entry).map(RawItem::wrap)
}
pub fn try_insert<'a, T>(
&'a mut self,
value: T,
) -> Result<WriteGuard<'a, T>, OccupiedError<'a, T>>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
match self.entry::<T>().0 {
Entry::Occupied(entry) => Err(OccupiedError { entry, value }),
Entry::Vacant(entry) => Ok(entry.insert(value)),
}
}
#[inline]
pub fn remove<T>(&mut self) -> Option<T>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
let key = StableTypeId::for_type::<T>();
self.raw
.remove(&key)
.and_then(|item| item.into_inner().ok())
}
#[inline]
pub fn contains<T>(&self) -> bool
where
T: 'static,
{
let key = StableTypeId::for_type::<T>();
self.raw.contains_key(&key)
}
#[inline]
pub fn contains_deserialized<T>(&self) -> bool
where
T: 'static,
{
let key = StableTypeId::for_type::<T>();
self.raw
.get(&key)
.map(|e| e.value.is_some())
.unwrap_or(false)
}
#[inline]
pub fn entry<'a, T>(&'a mut self) -> (Entry<'a, T>, Option<serde_value::DeserializerError>)
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
let key = StableTypeId::for_type::<T>();
let err = match self.raw.entry(key.clone()) {
hash_map::Entry::Occupied(mut inner) => inner.get_mut().get_mut::<T>().err(),
_ => None,
};
if err.is_some() {
self.raw.remove(&key);
}
match self.raw.entry(key) {
hash_map::Entry::Occupied(inner) => (Entry::Occupied(OccupiedEntry::new(inner)), err),
hash_map::Entry::Vacant(inner) => (Entry::Vacant(VacantEntry::new(inner)), err),
}
}
pub fn keys(&self) -> impl Iterator<Item = &StableTypeId> {
self.raw.keys()
}
#[inline]
pub fn as_raw(&self) -> &HashMap<StableTypeId, RawItem> {
&self.raw
}
#[inline]
pub unsafe fn as_raw_mut(&mut self) -> &mut HashMap<StableTypeId, RawItem> {
&mut self.raw
}
#[inline]
pub fn into_raw(self) -> HashMap<StableTypeId, RawItem> {
self.raw
}
#[inline]
pub unsafe fn from_raw(raw: HashMap<StableTypeId, RawItem>) -> SerializableAnyMap {
Self { raw }
}
}
impl<A: Any + Serialize + for<'de> Deserialize<'de>> Extend<Box<A>> for SerializableAnyMap {
#[inline]
fn extend<T: IntoIterator<Item = Box<A>>>(&mut self, iter: T) {
for item in iter {
let serialized = to_value(&*item).expect("serialization failed");
let _ = self.raw.insert(
StableTypeId::for_type::<T>(),
RawItem {
serialized,
value: Some(item),
},
);
}
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(transparent)]
pub struct RawItem {
serialized: Value,
#[serde(skip)]
#[serde(default)]
value: Option<Box<dyn Any>>,
}
impl Clone for RawItem {
fn clone(&self) -> Self {
RawItem {
serialized: self.serialized.clone(),
value: None, }
}
}
pub struct Item<T>(RawItem, PhantomData<T>);
impl<T> Item<T> {
pub fn try_get(&self) -> Option<&T>
where
T: for<'de> Deserialize<'de> + 'static,
{
self.0.value.as_ref()?.downcast_ref::<T>()
}
pub fn get(&mut self) -> Result<&T, serde_value::DeserializerError>
where
T: Serialize + for<'de> Deserialize<'de> + 'static,
{
self.0.get_mut().map(|x: WriteGuard<T>| x.into_ref())
}
pub fn get_mut<'a>(&'a mut self) -> Result<WriteGuard<'a, T>, serde_value::DeserializerError>
where
T: for<'de> Deserialize<'de> + Serialize + 'static,
{
if self.0.value.is_none() {
let deserialized = T::deserialize(self.0.serialized.clone())?;
self.0.value = Some(Box::new(deserialized));
}
Ok(WriteGuard::new(&mut self.0))
}
pub fn into_inner(mut self) -> Result<T, serde_value::DeserializerError>
where
T: for<'de> Deserialize<'de> + 'static,
{
self.0
.value
.take()
.map(|a| Ok(*a.downcast::<T>().unwrap()))
.unwrap_or_else(|| T::deserialize(self.0.serialized))
}
}
impl RawItem {
fn try_get<T>(&self) -> Option<&T>
where
T: for<'de> Deserialize<'de> + 'static,
{
self.value.as_ref()?.downcast_ref::<T>()
}
fn get<T>(&mut self) -> Result<&T, serde_value::DeserializerError>
where
T: Serialize + for<'de> Deserialize<'de> + 'static,
{
self.get_mut().map(|x: WriteGuard<T>| x.into_ref())
}
fn get_mut<'a, T>(&'a mut self) -> Result<WriteGuard<'a, T>, serde_value::DeserializerError>
where
T: for<'de> Deserialize<'de> + Serialize + 'static,
{
if self.value.is_none() {
let deserialized = T::deserialize(self.serialized.clone())?;
self.value = Some(Box::new(deserialized));
}
Ok(WriteGuard::new(self))
}
fn into_inner<T>(mut self) -> Result<T, serde_value::DeserializerError>
where
T: for<'de> Deserialize<'de> + 'static,
{
self.value
.take()
.map(|a| Ok(*a.downcast::<T>().unwrap()))
.unwrap_or_else(|| T::deserialize(self.serialized))
}
fn wrap<T>(self) -> Item<T> {
Item(self, PhantomData)
}
}