#![deny(missing_docs, unused, warnings)]
mod entry;
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};
use std::collections::hash_map;
use std::{any::Any, collections::HashMap};
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
#[serde(transparent)]
pub struct SerializableAnyMap {
raw: HashMap<String, Wrapper>,
}
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 shrink_to_fit(&mut self) {
self.raw.shrink_to_fit()
}
#[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 = key_for_type::<T>().to_string();
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,
{
Self::get_mut(self).map(|r| r.map(|v: WriteGuard<T>| v.into_ref()))
}
#[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,
{
let key = key_for_type::<T>().to_string();
Some(self.raw.get_mut(&key)?.get_mut())
}
#[inline]
pub fn get_serialized_value<T>(&self) -> Option<&Value>
where
T: 'static,
{
let key = key_for_type::<T>().to_string();
self.raw.get(&key).map(|e| &e.serialized)
}
#[inline]
pub unsafe fn insert_value_by_name(
&mut self,
type_name: String,
value: Value,
) -> Option<Value> {
let e = Wrapper {
serialized: value,
value: None,
};
self.raw.insert(type_name, e).map(|e| e.serialized)
}
#[inline]
pub fn insert<T>(&mut self, value: T) -> Option<Result<T, serde_value::DeserializerError>>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
let key = key_for_type::<T>().to_string();
let serialized = to_value(&value).expect("serialization failed");
let new_entry = Wrapper {
serialized,
value: Some(Box::new(value)),
};
self.raw
.insert(key, new_entry)
.map(|old| old.into_inner::<T>())
}
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>() {
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 = key_for_type::<T>().to_string();
self.raw
.remove(&key)
.and_then(|entry| entry.into_inner::<T>().ok())
}
#[inline]
pub fn contains<T>(&self) -> bool
where
T: 'static,
{
let key = key_for_type::<T>().to_string();
self.raw.contains_key(&key)
}
#[inline]
pub fn contains_deserialized<T>(&self) -> bool
where
T: 'static,
{
let key = key_for_type::<T>().to_string();
self.raw.contains_key(&key)
}
#[inline]
pub fn entry<T>(&mut self) -> Entry<'_, T>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
let key = key_for_type::<T>().to_string();
let should_remove = match self.raw.entry(key.clone()) {
hash_map::Entry::Occupied(mut inner) => inner.get_mut().get_mut::<T>().is_err(),
_ => false,
};
if should_remove {
self.raw.remove(&key);
}
match self.raw.entry(key) {
hash_map::Entry::Occupied(inner) => Entry::Occupied(OccupiedEntry::new(inner)),
hash_map::Entry::Vacant(inner) => Entry::Vacant(VacantEntry::new(inner)),
}
}
pub fn keys(&self) -> impl Iterator<Item = &String> {
self.raw.keys()
}
#[inline]
pub fn as_raw(&self) -> &HashMap<String, Wrapper> {
&self.raw
}
#[inline]
pub unsafe fn as_raw_mut(&mut self) -> &mut HashMap<String, Wrapper> {
&mut self.raw
}
#[inline]
pub fn into_raw(self) -> HashMap<String, Wrapper> {
self.raw
}
#[inline]
pub unsafe fn from_raw(raw: HashMap<String, Wrapper>) -> 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(
key_for_type::<T>().to_string(),
Wrapper {
serialized,
value: Some(item),
},
);
}
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(transparent)]
pub struct Wrapper {
serialized: Value,
#[serde(skip)]
#[serde(default)]
value: Option<Box<dyn Any>>,
}
impl Clone for Wrapper {
fn clone(&self) -> Self {
Wrapper {
serialized: self.serialized.clone(),
value: None, }
}
}
impl Wrapper {
pub fn try_get<T>(&self) -> Option<&T>
where
T: for<'de> Deserialize<'de> + 'static,
{
self.value.as_ref()?.downcast_ref::<T>()
}
pub 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())
}
pub 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))
}
pub 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 key_for_type<T: ?Sized>() -> String {
std::any::type_name::<T>().to_string()
}