micromegas_transit/
serialize.rs1#[allow(unsafe_code)]
2#[inline(always)]
3pub fn write_any<T>(buffer: &mut Vec<u8>, value: &T) {
4 let ptr = std::ptr::addr_of!(*value).cast::<u8>();
5 let slice = std::ptr::slice_from_raw_parts(ptr, std::mem::size_of::<T>());
6 unsafe {
7 buffer.extend_from_slice(&*slice);
8 }
9}
10
11#[allow(unsafe_code)]
12#[inline(always)]
18pub unsafe fn read_any<T>(ptr: *const u8) -> T {
19 unsafe { std::ptr::read_unaligned(ptr.cast::<T>()) }
20}
21
22pub fn advance_window(window: &[u8], offset: usize) -> &[u8] {
23 assert!(offset <= window.len());
24 &window[offset..]
25}
26
27pub fn read_consume_pod<T>(window: &mut &[u8]) -> T {
28 let object_size = std::mem::size_of::<T>();
29 let begin: *const u8 = window.as_ptr();
30 *window = advance_window(window, object_size);
31 unsafe { std::ptr::read_unaligned(begin.cast::<T>()) }
32}
33
34pub enum InProcSize {
36 Const(usize),
37 Dynamic,
38}
39
40pub trait InProcSerialize: Sized {
43 const IN_PROC_SIZE: InProcSize = InProcSize::Const(std::mem::size_of::<Self>());
44
45 fn get_value_size(&self) -> Option<u32> {
46 None
49 }
50
51 #[inline(always)]
52 fn write_value(&self, buffer: &mut Vec<u8>) {
53 assert!(matches!(Self::IN_PROC_SIZE, InProcSize::Const(_)));
54 #[allow(clippy::needless_borrow)]
55 write_any::<Self>(buffer, &self);
57 }
58
59 #[allow(unsafe_code)]
65 #[inline(always)]
66 unsafe fn read_value(mut window: &[u8]) -> Self {
67 let res = read_consume_pod(&mut window);
68 assert_eq!(window.len(), 0);
69 res
70 }
71}