facet_core/types/def/
slice.rs

1use crate::{PtrMut, ptr::PtrConst};
2
3use super::Shape;
4
5/// Fields for slice types
6#[derive(Clone, Copy, Debug)]
7#[repr(C)]
8pub struct SliceDef<'shape> {
9    /// vtable for interacting with the slice
10    pub vtable: &'shape SliceVTable,
11    /// shape of the items in the slice
12    pub t: &'shape Shape<'shape>,
13}
14
15impl<'shape> SliceDef<'shape> {
16    /// Returns a builder for SliceDef
17    pub const fn builder() -> SliceDefBuilder<'shape> {
18        SliceDefBuilder::new()
19    }
20
21    /// Returns the shape of the items in the slice
22    pub const fn t(&self) -> &'shape Shape<'shape> {
23        self.t
24    }
25}
26
27/// Builder for SliceDef
28pub struct SliceDefBuilder<'shape> {
29    vtable: Option<&'shape SliceVTable>,
30    t: Option<&'shape Shape<'shape>>,
31}
32
33impl<'shape> SliceDefBuilder<'shape> {
34    /// Creates a new SliceDefBuilder
35    #[allow(clippy::new_without_default)]
36    pub const fn new() -> Self {
37        Self {
38            vtable: None,
39            t: None,
40        }
41    }
42
43    /// Sets the vtable for the SliceDef
44    pub const fn vtable(mut self, vtable: &'shape SliceVTable) -> Self {
45        self.vtable = Some(vtable);
46        self
47    }
48
49    /// Sets the item shape for the SliceDef
50    pub const fn t(mut self, t: &'shape Shape<'shape>) -> Self {
51        self.t = Some(t);
52        self
53    }
54
55    /// Builds the SliceDef
56    pub const fn build(self) -> SliceDef<'shape> {
57        SliceDef {
58            vtable: self.vtable.unwrap(),
59            t: self.t.unwrap(),
60        }
61    }
62}
63
64/// Get the number of items in the slice
65///
66/// # Safety
67///
68/// The `slice` parameter must point to aligned, initialized memory of the correct type.
69pub type SliceLenFn = unsafe fn(slice: PtrConst) -> usize;
70
71/// Get pointer to the data buffer of the slice
72///
73/// # Safety
74///
75/// The `slice` parameter must point to aligned, initialized memory of the correct type.
76pub type SliceAsPtrFn = unsafe fn(slice: PtrConst) -> PtrConst;
77
78/// Get mutable pointer to the data buffer of the slice
79///
80/// # Safety
81///
82/// The `slice` parameter must point to aligned, initialized memory of the correct type.
83pub type SliceAsMutPtrFn = unsafe fn(slice: PtrMut) -> PtrMut;
84
85/// Virtual table for a slice-like type (like `Vec<T>`,
86/// but also `HashSet<T>`, etc.)
87#[derive(Clone, Copy, Debug)]
88#[repr(C)]
89pub struct SliceVTable {
90    /// Number of items in the slice
91    pub len: SliceLenFn,
92    /// Get pointer to the data buffer of the slice.
93    pub as_ptr: SliceAsPtrFn,
94    /// Get mutable pointer to the data buffer of the slice.
95    pub as_mut_ptr: SliceAsMutPtrFn,
96}
97
98impl SliceVTable {
99    /// Returns a builder for SliceVTable
100    pub const fn builder() -> SliceVTableBuilder {
101        SliceVTableBuilder::new()
102    }
103}
104
105/// Builds a [`SliceVTable`]
106pub struct SliceVTableBuilder {
107    as_ptr: Option<SliceAsPtrFn>,
108    as_mut_ptr: Option<SliceAsMutPtrFn>,
109    len: Option<SliceLenFn>,
110}
111
112impl SliceVTableBuilder {
113    /// Creates a new [`SliceVTableBuilder`] with all fields set to `None`.
114    #[allow(clippy::new_without_default)]
115    pub const fn new() -> Self {
116        Self {
117            len: None,
118            as_ptr: None,
119            as_mut_ptr: None,
120        }
121    }
122
123    /// Sets the `len` field
124    pub const fn len(mut self, f: SliceLenFn) -> Self {
125        self.len = Some(f);
126        self
127    }
128
129    /// Sets the as_ptr field
130    pub const fn as_ptr(mut self, f: SliceAsPtrFn) -> Self {
131        self.as_ptr = Some(f);
132        self
133    }
134
135    /// Sets the as_mut_ptr field
136    pub const fn as_mut_ptr(mut self, f: SliceAsMutPtrFn) -> Self {
137        self.as_mut_ptr = Some(f);
138        self
139    }
140
141    /// Builds the [`SliceVTable`] from the current state of the builder.
142    ///
143    /// # Panics
144    ///
145    /// This method will panic if any of the required fields are `None`.
146    pub const fn build(self) -> SliceVTable {
147        SliceVTable {
148            len: self.len.unwrap(),
149            as_ptr: self.as_ptr.unwrap(),
150            as_mut_ptr: self.as_mut_ptr.unwrap(),
151        }
152    }
153}