const_serialize/
primitive.rs1use crate::*;
2use std::mem::MaybeUninit;
3
4#[derive(Debug, Copy, Clone)]
6pub struct PrimitiveLayout {
7 pub(crate) size: usize,
8}
9
10impl PrimitiveLayout {
11 pub const fn new(size: usize) -> Self {
13 Self { size }
14 }
15
16 pub const unsafe fn read(self, byte_ptr: *const u8) -> u32 {
21 let mut value = 0;
22 let mut offset = 0;
23 while offset < self.size {
24 let byte = if cfg!(target_endian = "big") {
26 unsafe {
27 byte_ptr
28 .wrapping_byte_add((self.size - offset - 1) as _)
29 .read()
30 }
31 } else {
32 unsafe { byte_ptr.wrapping_byte_add(offset as _).read() }
33 };
34 value |= (byte as u32) << (offset * 8);
35 offset += 1;
36 }
37 value
38 }
39
40 pub const fn write(self, value: u32, out: &mut [MaybeUninit<u8>]) {
42 let bytes = value.to_ne_bytes();
43 let mut offset = 0;
44 while offset < self.size {
45 out[offset] = MaybeUninit::new(bytes[offset]);
46 offset += 1;
47 }
48 }
49}
50
51macro_rules! impl_serialize_const {
52 ($type:ty) => {
53 unsafe impl SerializeConst for $type {
54 const MEMORY_LAYOUT: Layout = Layout::Primitive(PrimitiveLayout {
55 size: std::mem::size_of::<$type>(),
56 });
57 }
58 };
59}
60
61impl_serialize_const!(u8);
62impl_serialize_const!(u16);
63impl_serialize_const!(u32);
64impl_serialize_const!(u64);
65impl_serialize_const!(i8);
66impl_serialize_const!(i16);
67impl_serialize_const!(i32);
68impl_serialize_const!(i64);
69impl_serialize_const!(bool);
70impl_serialize_const!(f32);
71impl_serialize_const!(f64);
72
73pub(crate) const unsafe fn serialize_const_primitive(
75 ptr: *const (),
76 to: ConstVec<u8>,
77 layout: &PrimitiveLayout,
78) -> ConstVec<u8> {
79 let ptr = ptr as *const u8;
80 let mut offset = 0;
81 let mut i64_bytes = [0u8; 8];
82 while offset < layout.size {
83 let byte = unsafe {
85 if cfg!(any(target_endian = "big", feature = "test-big-endian")) {
86 ptr.wrapping_byte_offset((layout.size - offset - 1) as _)
87 .read()
88 } else {
89 ptr.wrapping_byte_offset(offset as _).read()
90 }
91 };
92 i64_bytes[offset] = byte;
93 offset += 1;
94 }
95 let number = i64::from_ne_bytes(i64_bytes);
96 write_number(to, number)
97}
98
99pub(crate) const fn deserialize_const_primitive<'a>(
101 from: &'a [u8],
102 layout: &PrimitiveLayout,
103 out: &mut [MaybeUninit<u8>],
104) -> Option<&'a [u8]> {
105 let mut offset = 0;
106 let Ok((number, from)) = take_number(from) else {
107 return None;
108 };
109 let bytes = number.to_le_bytes();
110 while offset < layout.size {
111 let byte = bytes[offset];
113 if cfg!(any(target_endian = "big", feature = "test-big-endian")) {
114 out[layout.size - offset - 1] = MaybeUninit::new(byte);
115 } else {
116 out[offset] = MaybeUninit::new(byte);
117 }
118 offset += 1;
119 }
120 Some(from)
121}