planus/impls/
primitives.rs

1use core::mem::MaybeUninit;
2
3use crate::{
4    builder::Builder, errors::ErrorKind, slice_helpers::SliceWithStartOffset, traits::*, Cursor,
5};
6
7macro_rules! unsafe_gen_primitive_types {
8    ($ty:ty, $size:expr) => {
9        /// # Safety
10        /// `ALIGNMENT` and `SIZE` should match the actual alignment and size of the type.
11        unsafe impl Primitive for $ty {
12            const ALIGNMENT: usize = $size;
13            const SIZE: usize = $size;
14        }
15
16        impl WriteAsPrimitive<$ty> for $ty {
17            #[inline]
18            fn write<const N: usize>(&self, cursor: Cursor<'_, N>, _buffer_position: u32) {
19                cursor.assert_size().finish(self.to_le_bytes());
20            }
21        }
22
23        impl WriteAs<$ty> for $ty {
24            type Prepared = Self;
25            #[inline]
26            fn prepare(&self, _builder: &mut Builder) -> Self {
27                *self
28            }
29        }
30
31        impl WriteAsDefault<$ty, $ty> for $ty {
32            type Prepared = Self;
33            #[inline]
34            fn prepare(&self, _builder: &mut Builder, default: &$ty) -> Option<Self> {
35                #[allow(clippy::float_cmp)]
36                if self == default {
37                    None
38                } else {
39                    Some(*self)
40                }
41            }
42        }
43
44        impl WriteAsOptional<$ty> for $ty {
45            type Prepared = Self;
46            #[inline]
47            fn prepare(&self, _builder: &mut Builder) -> Option<Self> {
48                Some(*self)
49            }
50        }
51
52        impl<'buf> TableRead<'buf> for $ty {
53            #[inline]
54            fn from_buffer(
55                buffer: SliceWithStartOffset<'buf>,
56                offset: usize,
57            ) -> core::result::Result<$ty, ErrorKind> {
58                let buffer = buffer.advance_as_array(offset)?.as_array();
59                Ok(<$ty>::from_le_bytes(*buffer))
60            }
61        }
62    };
63}
64
65macro_rules! unsafe_gen_primitive_types_with_vectors {
66    ($ty:ty, $size:expr) => {
67        unsafe_gen_primitive_types!($ty, $size);
68        impl<'buf> VectorRead<'buf> for $ty {
69            const STRIDE: usize = $size;
70            #[inline]
71            unsafe fn from_buffer(buffer: SliceWithStartOffset<'buf>, offset: usize) -> $ty {
72                let buffer = buffer.unchecked_advance_as_array(offset).as_array();
73                <$ty>::from_le_bytes(*buffer)
74            }
75        }
76
77        /// # Safety
78        /// write_values initalizes bytes.
79        unsafe impl VectorWrite<$ty> for $ty {
80            const STRIDE: usize = $size;
81            type Value = $ty;
82            #[inline]
83            fn prepare(&self, _builder: &mut Builder) -> Self::Value {
84                *self
85            }
86
87            #[inline]
88            unsafe fn write_values(
89                values: &[$ty],
90                bytes: *mut MaybeUninit<u8>,
91                buffer_position: u32,
92            ) {
93                let bytes = bytes as *mut [MaybeUninit<u8>; $size];
94                for (i, v) in values.iter().enumerate() {
95                    v.write(
96                        Cursor::new(&mut *bytes.add(i)),
97                        buffer_position - ($size * i) as u32,
98                    );
99                }
100            }
101        }
102    };
103}
104
105unsafe_gen_primitive_types!(i8, core::mem::size_of::<i8>());
106unsafe_gen_primitive_types!(u8, core::mem::size_of::<u8>());
107unsafe_gen_primitive_types_with_vectors!(i16, core::mem::size_of::<i16>());
108unsafe_gen_primitive_types_with_vectors!(u16, core::mem::size_of::<u16>());
109unsafe_gen_primitive_types_with_vectors!(i32, core::mem::size_of::<i32>());
110unsafe_gen_primitive_types_with_vectors!(u32, core::mem::size_of::<u32>());
111unsafe_gen_primitive_types_with_vectors!(i64, core::mem::size_of::<i64>());
112unsafe_gen_primitive_types_with_vectors!(u64, core::mem::size_of::<u64>());
113unsafe_gen_primitive_types_with_vectors!(f32, core::mem::size_of::<f32>());
114unsafe_gen_primitive_types_with_vectors!(f64, core::mem::size_of::<f64>());