facet_core/types/def/
map.rs

1use crate::ptr::{PtrConst, PtrMut, PtrUninit};
2
3use super::{IterVTable, Shape};
4
5/// Fields for map types
6#[derive(Clone, Copy, Debug)]
7#[repr(C)]
8pub struct MapDef<'shape> {
9    /// vtable for interacting with the map
10    pub vtable: &'shape MapVTable,
11    /// shape of the keys in the map
12    pub k: fn() -> &'shape Shape<'shape>,
13    /// shape of the values in the map
14    pub v: fn() -> &'shape Shape<'shape>,
15}
16
17impl<'shape> MapDef<'shape> {
18    /// Returns a builder for MapDef
19    pub const fn builder() -> MapDefBuilder<'shape> {
20        MapDefBuilder::new()
21    }
22
23    /// Returns the shape of the keys of the map
24    pub fn k(&self) -> &'shape Shape<'shape> {
25        (self.k)()
26    }
27
28    /// Returns the shape of the values of the map
29    pub fn v(&self) -> &'shape Shape<'shape> {
30        (self.v)()
31    }
32}
33
34/// Builder for MapDef
35pub struct MapDefBuilder<'shape> {
36    vtable: Option<&'shape MapVTable>,
37    k: Option<fn() -> &'shape Shape<'shape>>,
38    v: Option<fn() -> &'shape Shape<'shape>>,
39}
40
41impl<'shape> MapDefBuilder<'shape> {
42    /// Creates a new MapDefBuilder
43    #[allow(clippy::new_without_default)]
44    pub const fn new() -> Self {
45        Self {
46            vtable: None,
47            k: None,
48            v: None,
49        }
50    }
51
52    /// Sets the vtable for the MapDef
53    pub const fn vtable(mut self, vtable: &'shape MapVTable) -> Self {
54        self.vtable = Some(vtable);
55        self
56    }
57
58    /// Sets the key shape for the MapDef
59    pub const fn k(mut self, k: fn() -> &'shape Shape<'shape>) -> Self {
60        self.k = Some(k);
61        self
62    }
63
64    /// Sets the value shape for the MapDef
65    pub const fn v(mut self, v: fn() -> &'shape Shape<'shape>) -> Self {
66        self.v = Some(v);
67        self
68    }
69
70    /// Builds the MapDef
71    pub const fn build(self) -> MapDef<'shape> {
72        MapDef {
73            vtable: self.vtable.unwrap(),
74            k: self.k.unwrap(),
75            v: self.v.unwrap(),
76        }
77    }
78}
79
80/// Initialize a map in place with a given capacity
81///
82/// # Safety
83///
84/// The `map` parameter must point to uninitialized memory of sufficient size.
85/// The function must properly initialize the memory.
86pub type MapInitInPlaceWithCapacityFn =
87    for<'mem> unsafe fn(map: PtrUninit<'mem>, capacity: usize) -> PtrMut<'mem>;
88
89/// Insert a key-value pair into the map
90///
91/// # Safety
92///
93/// The `map` parameter must point to aligned, initialized memory of the correct type.
94/// `key` and `value` are moved out of (with [`core::ptr::read`]) — they should be deallocated
95/// afterwards (e.g. with [`core::mem::forget`]) but NOT dropped.
96pub type MapInsertFn =
97    for<'map, 'key, 'value> unsafe fn(map: PtrMut<'map>, key: PtrMut<'key>, value: PtrMut<'value>);
98
99/// Get the number of entries in the map
100///
101/// # Safety
102///
103/// The `map` parameter must point to aligned, initialized memory of the correct type.
104pub type MapLenFn = for<'map> unsafe fn(map: PtrConst<'map>) -> usize;
105
106/// Check if the map contains a key
107///
108/// # Safety
109///
110/// The `map` parameter must point to aligned, initialized memory of the correct type.
111pub type MapContainsKeyFn =
112    for<'map, 'key> unsafe fn(map: PtrConst<'map>, key: PtrConst<'key>) -> bool;
113
114/// Get pointer to a value for a given key, returns None if not found
115///
116/// # Safety
117///
118/// The `map` parameter must point to aligned, initialized memory of the correct type.
119pub type MapGetValuePtrFn =
120    for<'map, 'key> unsafe fn(map: PtrConst<'map>, key: PtrConst<'key>) -> Option<PtrConst<'map>>;
121
122/// Virtual table for a Map<K, V>
123#[derive(Clone, Copy, Debug)]
124#[repr(C)]
125pub struct MapVTable {
126    /// cf. [`MapInitInPlaceWithCapacityFn`]
127    pub init_in_place_with_capacity_fn: MapInitInPlaceWithCapacityFn,
128
129    /// cf. [`MapInsertFn`]
130    pub insert_fn: MapInsertFn,
131
132    /// cf. [`MapLenFn`]
133    pub len_fn: MapLenFn,
134
135    /// cf. [`MapContainsKeyFn`]
136    pub contains_key_fn: MapContainsKeyFn,
137
138    /// cf. [`MapGetValuePtrFn`]
139    pub get_value_ptr_fn: MapGetValuePtrFn,
140
141    /// Virtual table for map iterator operations
142    pub iter_vtable: IterVTable<(PtrConst<'static>, PtrConst<'static>)>,
143}
144
145impl MapVTable {
146    /// Returns a builder for MapVTable
147    pub const fn builder() -> MapVTableBuilder {
148        MapVTableBuilder::new()
149    }
150}
151
152/// Builds a [`MapVTable`]
153pub struct MapVTableBuilder {
154    init_in_place_with_capacity_fn: Option<MapInitInPlaceWithCapacityFn>,
155    insert_fn: Option<MapInsertFn>,
156    len_fn: Option<MapLenFn>,
157    contains_key_fn: Option<MapContainsKeyFn>,
158    get_value_ptr_fn: Option<MapGetValuePtrFn>,
159    iter_vtable: Option<IterVTable<(PtrConst<'static>, PtrConst<'static>)>>,
160}
161
162impl MapVTableBuilder {
163    /// Creates a new [`MapVTableBuilder`] with all fields set to `None`.
164    #[allow(clippy::new_without_default)]
165    pub const fn new() -> Self {
166        Self {
167            init_in_place_with_capacity_fn: None,
168            insert_fn: None,
169            len_fn: None,
170            contains_key_fn: None,
171            get_value_ptr_fn: None,
172            iter_vtable: None,
173        }
174    }
175
176    /// Sets the init_in_place_with_capacity_fn field
177    pub const fn init_in_place_with_capacity(mut self, f: MapInitInPlaceWithCapacityFn) -> Self {
178        self.init_in_place_with_capacity_fn = Some(f);
179        self
180    }
181
182    /// Sets the insert_fn field
183    pub const fn insert(mut self, f: MapInsertFn) -> Self {
184        self.insert_fn = Some(f);
185        self
186    }
187
188    /// Sets the len_fn field
189    pub const fn len(mut self, f: MapLenFn) -> Self {
190        self.len_fn = Some(f);
191        self
192    }
193
194    /// Sets the contains_key_fn field
195    pub const fn contains_key(mut self, f: MapContainsKeyFn) -> Self {
196        self.contains_key_fn = Some(f);
197        self
198    }
199
200    /// Sets the get_value_ptr_fn field
201    pub const fn get_value_ptr(mut self, f: MapGetValuePtrFn) -> Self {
202        self.get_value_ptr_fn = Some(f);
203        self
204    }
205
206    /// Sets the iter_vtable field
207    pub const fn iter_vtable(
208        mut self,
209        vtable: IterVTable<(PtrConst<'static>, PtrConst<'static>)>,
210    ) -> Self {
211        self.iter_vtable = Some(vtable);
212        self
213    }
214
215    /// Builds the [`MapVTable`] from the current state of the builder.
216    ///
217    /// # Panics
218    ///
219    /// This method will panic if any of the required fields are `None`.
220    pub const fn build(self) -> MapVTable {
221        MapVTable {
222            init_in_place_with_capacity_fn: self.init_in_place_with_capacity_fn.unwrap(),
223            insert_fn: self.insert_fn.unwrap(),
224            len_fn: self.len_fn.unwrap(),
225            contains_key_fn: self.contains_key_fn.unwrap(),
226            get_value_ptr_fn: self.get_value_ptr_fn.unwrap(),
227            iter_vtable: self.iter_vtable.unwrap(),
228        }
229    }
230}