use crate::PokeValueUninit;
use facet_core::{MapDef, MapVTable, Opaque, OpaqueConst, OpaqueUninit, Shape};
pub struct PokeMapUninit<'mem> {
data: OpaqueUninit<'mem>,
shape: &'static Shape,
def: MapDef,
}
impl<'mem> PokeMapUninit<'mem> {
#[inline(always)]
pub fn into_value(self) -> PokeValueUninit<'mem> {
unsafe { PokeValueUninit::new(self.data, self.shape) }
}
#[inline(always)]
pub fn shape(&self) -> &'static Shape {
self.shape
}
pub(crate) unsafe fn new(data: OpaqueUninit<'mem>, shape: &'static Shape, def: MapDef) -> Self {
Self { data, shape, def }
}
pub fn init(self, size_hint: Option<usize>) -> Result<PokeMap<'mem>, OpaqueUninit<'mem>> {
let res = if let Some(capacity) = size_hint {
let init_in_place_with_capacity = self.def.vtable.init_in_place_with_capacity_fn;
unsafe { init_in_place_with_capacity(self.data, capacity) }
} else {
let pv = unsafe { PokeValueUninit::new(self.data, self.shape) };
pv.default_in_place().map_err(|_| ())
};
let data = res.map_err(|_| self.data)?;
Ok(unsafe { PokeMap::new(data, self.shape, self.def) })
}
}
pub struct PokeMap<'mem> {
data: Opaque<'mem>,
#[allow(dead_code)]
shape: &'static Shape,
def: MapDef,
}
impl<'mem> PokeMap<'mem> {
#[inline]
pub(crate) unsafe fn new(data: Opaque<'mem>, shape: &'static Shape, def: MapDef) -> Self {
Self { data, shape, def }
}
#[inline(always)]
pub fn shape(&self) -> &'static Shape {
self.shape
}
#[inline(always)]
pub fn map_vtable(&self) -> &'static MapVTable {
self.def.vtable
}
#[inline]
pub unsafe fn insert(&mut self, key: Opaque<'_>, value: Opaque<'_>) {
unsafe { (self.map_vtable().insert_fn)(self.data, key, value) }
}
#[inline]
pub fn len(&self) -> usize {
unsafe { (self.map_vtable().len_fn)(self.data.as_const()) }
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn contains_key(&self, key: OpaqueConst<'_>) -> bool {
unsafe { (self.map_vtable().contains_key_fn)(self.data.as_const(), key) }
}
#[inline]
pub fn get_value_ptr<'key>(&self, key: OpaqueConst<'key>) -> Option<OpaqueConst<'mem>> {
unsafe { (self.map_vtable().get_value_ptr_fn)(self.data.as_const(), key) }
}
pub fn build_in_place(self) -> Opaque<'mem> {
self.data
}
#[inline]
pub fn def(&self) -> &MapDef {
&self.def
}
}