planus/impls/
offset.rs

1use core::mem::MaybeUninit;
2
3use crate::{builder::Builder, traits::*, Cursor, Offset};
4
5/// # Safety
6/// An offset is a 32-bit unsigned integer + a zero-sized type.
7unsafe impl<T: ?Sized> Primitive for Offset<T> {
8    const ALIGNMENT: usize = 4;
9    const SIZE: usize = 4;
10}
11
12impl<T: ?Sized> WriteAsPrimitive<Offset<T>> for Offset<T> {
13    #[inline]
14    fn write<const N: usize>(&self, cursor: Cursor<'_, N>, buffer_position: u32) {
15        cursor
16            .assert_size()
17            .finish(u32::to_le_bytes(buffer_position - self.offset));
18    }
19}
20
21impl<T: ?Sized> WriteAsOffset<T> for Offset<T> {
22    fn prepare(&self, _builder: &mut Builder) -> Offset<T> {
23        *self
24    }
25}
26
27impl<T: ?Sized> WriteAs<Offset<T>> for Offset<T> {
28    type Prepared = Self;
29    #[inline]
30    fn prepare(&self, _builder: &mut Builder) -> Self {
31        *self
32    }
33}
34
35impl<T: ?Sized> WriteAsOptional<Offset<T>> for Offset<T> {
36    type Prepared = Self;
37    #[inline]
38    fn prepare(&self, _builder: &mut Builder) -> Option<Self> {
39        Some(*self)
40    }
41}
42
43impl<T: ?Sized, D> WriteAsDefault<Offset<T>, D> for Offset<T> {
44    type Prepared = Self;
45    #[inline]
46    fn prepare(&self, _builder: &mut Builder, _default: &D) -> Option<Self> {
47        Some(*self)
48    }
49}
50
51// # Safety
52// The implementation of `write_values` initializes all the bytes.
53unsafe impl<T: ?Sized> VectorWrite<Offset<T>> for Offset<T> {
54    const STRIDE: usize = 4;
55    type Value = Offset<T>;
56
57    #[inline]
58    fn prepare(&self, _builder: &mut Builder) -> Self::Value {
59        *self
60    }
61
62    #[inline]
63    unsafe fn write_values(
64        values: &[Offset<T>],
65        bytes: *mut MaybeUninit<u8>,
66        buffer_position: u32,
67    ) {
68        let bytes = bytes as *mut [MaybeUninit<u8>; 4];
69        for (i, v) in values.iter().enumerate() {
70            v.write(
71                Cursor::new(&mut *bytes.add(i)),
72                buffer_position - (Self::STRIDE * i) as u32,
73            );
74        }
75    }
76}