use std::marker::PhantomData;
use crate::{
access::{Access, AccessError, FromAccess},
views::{IndexAddress, IndexType, RawAccess, RawAccessMut, View, ViewWithMetadata},
BinaryValue,
};
#[derive(Debug)]
pub struct Entry<T: RawAccess, V> {
base: View<T>,
_v: PhantomData<V>,
}
impl<T, V> FromAccess<T> for Entry<T::Base, V>
where
T: Access,
V: BinaryValue,
{
fn from_access(access: T, addr: IndexAddress) -> Result<Self, AccessError> {
let view = access.get_or_create_view(addr, IndexType::Entry)?;
Ok(Self::new(view))
}
}
impl<T, V> Entry<T, V>
where
T: RawAccess,
V: BinaryValue,
{
fn new(view: ViewWithMetadata<T>) -> Self {
let base = view.into();
Self {
base,
_v: PhantomData,
}
}
pub fn get(&self) -> Option<V> {
self.base.get(&())
}
pub fn exists(&self) -> bool {
self.base.contains(&())
}
}
impl<T, V> Entry<T, V>
where
T: RawAccessMut,
V: BinaryValue,
{
pub fn set(&mut self, value: V) {
self.base.put(&(), value)
}
pub fn remove(&mut self) {
self.base.remove(&())
}
pub fn take(&mut self) -> Option<V> {
let value = self.get();
if value.is_some() {
self.remove();
}
value
}
pub fn swap(&mut self, value: V) -> Option<V> {
let previous = self.get();
self.set(value);
previous
}
}