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