facet_core/types/
map.rs

1use crate::ptr::{PtrConst, PtrMut, PtrUninit};
2
3use super::Shape;
4
5/// Fields for map types
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
7#[repr(C)]
8#[non_exhaustive]
9pub struct MapDef {
10    /// vtable for interacting with the map
11    pub vtable: &'static MapVTable,
12    /// shape of the keys in the map
13    pub k: &'static Shape,
14    /// shape of the values in the map
15    pub v: &'static Shape,
16}
17
18impl MapDef {
19    /// Returns a builder for MapDef
20    pub const fn builder() -> MapDefBuilder {
21        MapDefBuilder::new()
22    }
23}
24
25/// Builder for MapDef
26pub struct MapDefBuilder {
27    vtable: Option<&'static MapVTable>,
28    k: Option<&'static Shape>,
29    v: Option<&'static Shape>,
30}
31
32impl MapDefBuilder {
33    /// Creates a new MapDefBuilder
34    #[allow(clippy::new_without_default)]
35    pub const fn new() -> Self {
36        Self {
37            vtable: None,
38            k: None,
39            v: None,
40        }
41    }
42
43    /// Sets the vtable for the MapDef
44    pub const fn vtable(mut self, vtable: &'static MapVTable) -> Self {
45        self.vtable = Some(vtable);
46        self
47    }
48
49    /// Sets the key shape for the MapDef
50    pub const fn k(mut self, k: &'static Shape) -> Self {
51        self.k = Some(k);
52        self
53    }
54
55    /// Sets the value shape for the MapDef
56    pub const fn v(mut self, v: &'static Shape) -> Self {
57        self.v = Some(v);
58        self
59    }
60
61    /// Builds the MapDef
62    pub const fn build(self) -> MapDef {
63        MapDef {
64            vtable: self.vtable.unwrap(),
65            k: self.k.unwrap(),
66            v: self.v.unwrap(),
67        }
68    }
69}
70
71/// Initialize a map in place with a given capacity
72///
73/// # Safety
74///
75/// The `map` parameter must point to uninitialized memory of sufficient size.
76/// The function must properly initialize the memory.
77pub type MapInitInPlaceWithCapacityFn =
78    for<'mem> unsafe fn(map: PtrUninit<'mem>, capacity: usize) -> PtrMut<'mem>;
79
80/// Insert a key-value pair into the map
81///
82/// # Safety
83///
84/// The `map` parameter must point to aligned, initialized memory of the correct type.
85/// `key` and `value` are moved out of (with [`core::ptr::read`]) — they should be deallocated
86/// afterwards but NOT dropped.
87pub type MapInsertFn =
88    for<'map, 'key, 'value> unsafe fn(map: PtrMut<'map>, key: PtrMut<'key>, value: PtrMut<'value>);
89
90/// Get the number of entries in the map
91///
92/// # Safety
93///
94/// The `map` parameter must point to aligned, initialized memory of the correct type.
95pub type MapLenFn = for<'map> unsafe fn(map: PtrConst<'map>) -> usize;
96
97/// Check if the map contains a key
98///
99/// # Safety
100///
101/// The `map` parameter must point to aligned, initialized memory of the correct type.
102pub type MapContainsKeyFn =
103    for<'map, 'key> unsafe fn(map: PtrConst<'map>, key: PtrConst<'key>) -> bool;
104
105/// Get pointer to a value for a given key, returns None if not found
106///
107/// # Safety
108///
109/// The `map` parameter must point to aligned, initialized memory of the correct type.
110pub type MapGetValuePtrFn =
111    for<'map, 'key> unsafe fn(map: PtrConst<'map>, key: PtrConst<'key>) -> Option<PtrConst<'map>>;
112
113/// Get an iterator over the map
114///
115/// # Safety
116///
117/// The `map` parameter must point to aligned, initialized memory of the correct type.
118pub type MapIterFn = for<'map> unsafe fn(map: PtrConst<'map>) -> PtrMut<'map>;
119
120/// Get the next key-value pair from the iterator
121///
122/// # Safety
123///
124/// The `iter` parameter must point to aligned, initialized memory of the correct type.
125pub type MapIterNextFn =
126    for<'iter> unsafe fn(iter: PtrMut<'iter>) -> Option<(PtrConst<'iter>, PtrConst<'iter>)>;
127
128/// Deallocate the iterator
129///
130/// # Safety
131///
132/// The `iter` parameter must point to aligned, initialized memory of the correct type.
133pub type MapIterDeallocFn = for<'iter> unsafe fn(iter: PtrMut<'iter>);
134
135/// VTable for an iterator over a map
136#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
137#[repr(C)]
138#[non_exhaustive]
139pub struct MapIterVTable {
140    /// cf. [`MapIterNextFn`]
141    pub next: MapIterNextFn,
142
143    /// cf. [`MapIterDeallocFn`]
144    pub dealloc: MapIterDeallocFn,
145}
146
147impl MapIterVTable {
148    /// Returns a builder for MapIterVTable
149    pub const fn builder() -> MapIterVTableBuilder {
150        MapIterVTableBuilder::new()
151    }
152}
153
154/// Builds a [`MapIterVTable`]
155pub struct MapIterVTableBuilder {
156    next: Option<MapIterNextFn>,
157    dealloc: Option<MapIterDeallocFn>,
158}
159
160impl MapIterVTableBuilder {
161    /// Creates a new [`MapIterVTableBuilder`] with all fields set to `None`.
162    #[allow(clippy::new_without_default)]
163    pub const fn new() -> Self {
164        Self {
165            next: None,
166            dealloc: None,
167        }
168    }
169
170    /// Sets the next field
171    pub const fn next(mut self, f: MapIterNextFn) -> Self {
172        self.next = Some(f);
173        self
174    }
175
176    /// Sets the dealloc field
177    pub const fn dealloc(mut self, f: MapIterDeallocFn) -> Self {
178        self.dealloc = Some(f);
179        self
180    }
181
182    /// Builds the [`MapIterVTable`] from the current state of the builder.
183    ///
184    /// # Panics
185    ///
186    /// This method will panic if any of the required fields are `None`.
187    pub const fn build(self) -> MapIterVTable {
188        MapIterVTable {
189            next: self.next.unwrap(),
190            dealloc: self.dealloc.unwrap(),
191        }
192    }
193}
194
195/// Virtual table for a Map<K, V>
196#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
197#[repr(C)]
198pub struct MapVTable {
199    /// cf. [`MapInitInPlaceWithCapacityFn`]
200    pub init_in_place_with_capacity_fn: MapInitInPlaceWithCapacityFn,
201
202    /// cf. [`MapInsertFn`]
203    pub insert_fn: MapInsertFn,
204
205    /// cf. [`MapLenFn`]
206    pub len_fn: MapLenFn,
207
208    /// cf. [`MapContainsKeyFn`]
209    pub contains_key_fn: MapContainsKeyFn,
210
211    /// cf. [`MapGetValuePtrFn`]
212    pub get_value_ptr_fn: MapGetValuePtrFn,
213
214    /// cf. [`MapIterFn`]
215    pub iter_fn: MapIterFn,
216
217    /// Virtual table for map iterator operations
218    pub iter_vtable: MapIterVTable,
219}
220
221impl MapVTable {
222    /// Returns a builder for MapVTable
223    pub const fn builder() -> MapVTableBuilder {
224        MapVTableBuilder::new()
225    }
226}
227
228/// Builds a [`MapVTable`]
229pub struct MapVTableBuilder {
230    init_in_place_with_capacity_fn: Option<MapInitInPlaceWithCapacityFn>,
231    insert_fn: Option<MapInsertFn>,
232    len_fn: Option<MapLenFn>,
233    contains_key_fn: Option<MapContainsKeyFn>,
234    get_value_ptr_fn: Option<MapGetValuePtrFn>,
235    iter_fn: Option<MapIterFn>,
236    iter_vtable: Option<MapIterVTable>,
237}
238
239impl MapVTableBuilder {
240    /// Creates a new [`MapVTableBuilder`] with all fields set to `None`.
241    #[allow(clippy::new_without_default)]
242    pub const fn new() -> Self {
243        Self {
244            init_in_place_with_capacity_fn: None,
245            insert_fn: None,
246            len_fn: None,
247            contains_key_fn: None,
248            get_value_ptr_fn: None,
249            iter_fn: None,
250            iter_vtable: None,
251        }
252    }
253
254    /// Sets the init_in_place_with_capacity_fn field
255    pub const fn init_in_place_with_capacity(mut self, f: MapInitInPlaceWithCapacityFn) -> Self {
256        self.init_in_place_with_capacity_fn = Some(f);
257        self
258    }
259
260    /// Sets the insert_fn field
261    pub const fn insert(mut self, f: MapInsertFn) -> Self {
262        self.insert_fn = Some(f);
263        self
264    }
265
266    /// Sets the len_fn field
267    pub const fn len(mut self, f: MapLenFn) -> Self {
268        self.len_fn = Some(f);
269        self
270    }
271
272    /// Sets the contains_key_fn field
273    pub const fn contains_key(mut self, f: MapContainsKeyFn) -> Self {
274        self.contains_key_fn = Some(f);
275        self
276    }
277
278    /// Sets the get_value_ptr_fn field
279    pub const fn get_value_ptr(mut self, f: MapGetValuePtrFn) -> Self {
280        self.get_value_ptr_fn = Some(f);
281        self
282    }
283
284    /// Sets the iter_fn field
285    pub const fn iter(mut self, f: MapIterFn) -> Self {
286        self.iter_fn = Some(f);
287        self
288    }
289
290    /// Sets the iter_vtable field
291    pub const fn iter_vtable(mut self, vtable: MapIterVTable) -> Self {
292        self.iter_vtable = Some(vtable);
293        self
294    }
295
296    /// Builds the [`MapVTable`] from the current state of the builder.
297    ///
298    /// # Panics
299    ///
300    /// This method will panic if any of the required fields are `None`.
301    pub const fn build(self) -> MapVTable {
302        MapVTable {
303            init_in_place_with_capacity_fn: self.init_in_place_with_capacity_fn.unwrap(),
304            insert_fn: self.insert_fn.unwrap(),
305            len_fn: self.len_fn.unwrap(),
306            contains_key_fn: self.contains_key_fn.unwrap(),
307            get_value_ptr_fn: self.get_value_ptr_fn.unwrap(),
308            iter_fn: self.iter_fn.unwrap(),
309            iter_vtable: self.iter_vtable.unwrap(),
310        }
311    }
312}