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