use crate::RawItem;
use crate::stable_type_id::StableTypeId;
use crate::write_guard::WriteGuard;
use serde::{Deserialize, Serialize};
use serde_value::{Value, to_value};
use std::any::Any;
use std::collections::hash_map;
pub enum Entry<'a, T> {
Occupied(OccupiedEntry<'a, T>),
Vacant(VacantEntry<'a, T>),
}
pub struct OccupiedEntry<'a, T> {
inner: hash_map::OccupiedEntry<'a, StableTypeId, RawItem>,
_marker: std::marker::PhantomData<T>,
}
pub struct VacantEntry<'a, T> {
inner: hash_map::VacantEntry<'a, StableTypeId, RawItem>,
_marker: std::marker::PhantomData<T>,
}
impl<'a, T> Entry<'a, T>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
#[inline]
pub fn or_insert(
self,
default: T,
) -> Result<WriteGuard<'a, T>, serde_value::DeserializerError> {
match self {
Entry::Occupied(inner) => inner.into_mut(),
Entry::Vacant(inner) => Ok(inner.insert(default)),
}
}
#[inline]
pub fn or_insert_with<F: FnOnce() -> T>(
self,
default: F,
) -> Result<WriteGuard<'a, T>, serde_value::DeserializerError> {
match self {
Entry::Occupied(inner) => inner.into_mut(),
Entry::Vacant(inner) => Ok(inner.insert(default())),
}
}
#[inline]
pub fn or_default(self) -> Result<WriteGuard<'a, T>, serde_value::DeserializerError>
where
T: Default,
{
match self {
Entry::Occupied(inner) => inner.into_mut(),
Entry::Vacant(inner) => Ok(inner.insert(Default::default())),
}
}
#[inline]
pub fn and_modify<F: FnOnce(WriteGuard<T>)>(self, f: F) -> Self {
match self {
Entry::Occupied(mut inner) => {
let _ = inner.get_mut().map(f);
Entry::Occupied(inner)
}
Entry::Vacant(inner) => Entry::Vacant(inner),
}
}
pub fn into_occupied(self) -> Option<OccupiedEntry<'a, T>> {
match self {
Entry::Occupied(e) => Some(e),
Entry::Vacant(_) => None,
}
}
pub fn into_vacant(self) -> Option<VacantEntry<'a, T>> {
match self {
Entry::Vacant(e) => Some(e),
Entry::Occupied(_) => None,
}
}
}
impl<'a, T> OccupiedEntry<'a, T>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
pub(crate) fn new(inner: hash_map::OccupiedEntry<'a, StableTypeId, RawItem>) -> Self {
OccupiedEntry {
inner,
_marker: std::marker::PhantomData,
}
}
pub fn try_get(&self) -> Option<&T> {
self.inner.get().try_get::<T>()
}
#[inline]
pub fn get(&mut self) -> Result<&T, serde_value::DeserializerError> {
self.inner.get_mut().get()
}
#[inline]
pub fn get_mut<'b>(&'b mut self) -> Result<WriteGuard<'b, T>, serde_value::DeserializerError> {
self.inner.get_mut().get_mut()
}
#[inline]
pub fn remove(self) -> Result<T, serde_value::DeserializerError> {
self.inner.remove().into_inner()
}
#[inline]
pub fn into_mut(self) -> Result<WriteGuard<'a, T>, serde_value::DeserializerError> {
self.inner.into_mut().get_mut()
}
#[inline]
pub fn insert(&mut self, value: T) -> Result<T, serde_value::DeserializerError> {
let serialized = to_value(&value).expect("serialization failed");
self.inner
.insert(RawItem {
serialized,
value: Some(Box::new(value)),
})
.into_inner()
}
}
impl<'a, T> VacantEntry<'a, T>
where
T: Serialize + for<'de> Deserialize<'de> + Any + 'static,
{
pub(crate) fn new(inner: hash_map::VacantEntry<'a, StableTypeId, RawItem>) -> Self {
VacantEntry {
inner,
_marker: std::marker::PhantomData,
}
}
pub fn insert(self, value: T) -> WriteGuard<'a, T> {
let serialized = to_value(&value).expect("serialization failed");
let entry = RawItem {
serialized,
value: Some(Box::new(value)),
};
WriteGuard::new(self.inner.insert(entry))
}
pub unsafe fn insert_serialized(self, value: Value) {
self.inner.insert(RawItem {
serialized: value,
value: None,
});
}
}
pub struct OccupiedError<'a, V: 'a> {
pub entry: OccupiedEntry<'a, V>,
pub value: V,
}