planus/traits/
mod.rs

1use crate::{
2    builder::Builder, errors::ErrorKind, slice_helpers::SliceWithStartOffset, Cursor, Offset,
3    Result, UnionOffset,
4};
5use core::mem::MaybeUninit;
6
7#[doc(hidden)]
8pub trait Primitive {
9    const ALIGNMENT: usize;
10    const ALIGNMENT_MASK: usize = Self::ALIGNMENT - 1;
11    const SIZE: usize;
12}
13
14/// Interface for getting a view into serialized data.
15///
16/// To get an owned variant use [`TryInto`] on the `Ref` type. Note that for
17/// nested types with lots of sharing the owned variants can be much larger than
18/// the serialized representation.
19///
20/// # Examples
21///
22/// ```no_run
23/// use std::error::Error;
24/// use planus::ReadAsRoot;
25/// use planus_example::monster_generated::my_game::sample::{Monster, MonsterRef};
26///
27/// fn main() -> Result<(), Box<dyn Error>> {
28///     let buf = std::fs::read("monster.bin")?;
29///     let monster: MonsterRef<'_> = MonsterRef::read_as_root(&buf)?;
30///     let monster_health = monster.hp()?;
31///     let owned_monster: Monster = monster.try_into().expect("invalid monster");
32///     Ok(())
33/// }
34pub trait ReadAsRoot<'a>: Sized {
35    /// Takes a slice assumed to be of this type and returns a view into it.
36    ///
37    /// If the data is not valid for this type the field accessors will give
38    /// errors or invalid values, but will still be memory safe.
39    fn read_as_root(slice: &'a [u8]) -> Result<Self>;
40}
41
42/// Trait used by generated code to serialize primitive types.
43pub trait WriteAs<P: Primitive> {
44    #[doc(hidden)]
45    type Prepared: WriteAsPrimitive<P>;
46    #[doc(hidden)]
47    fn prepare(&self, builder: &mut Builder) -> Self::Prepared;
48}
49
50/// Trait used by generated code to serialize primitive types with default values.
51pub trait WriteAsDefault<P: Primitive, D: ?Sized> {
52    #[doc(hidden)]
53    type Prepared: WriteAsPrimitive<P>;
54    #[doc(hidden)]
55    fn prepare(&self, builder: &mut Builder, default: &D) -> Option<Self::Prepared>;
56}
57
58/// Trait used by generated code to serialize optional primitive types.
59pub trait WriteAsOptional<P: Primitive> {
60    #[doc(hidden)]
61    type Prepared: WriteAsPrimitive<P>;
62    #[doc(hidden)]
63    fn prepare(&self, builder: &mut Builder) -> Option<Self::Prepared>;
64}
65
66/// Trait used by generated code to serialize offsets to already serialized data.
67pub trait WriteAsOffset<T: ?Sized> {
68    #[doc(hidden)]
69    fn prepare(&self, builder: &mut Builder) -> Offset<T>;
70}
71
72/// Trait used by generated code to serialize offsets to unions.
73pub trait WriteAsUnion<T: ?Sized> {
74    #[doc(hidden)]
75    fn prepare(&self, builder: &mut Builder) -> UnionOffset<T>;
76}
77
78/// Trait used by generated code to serialize offsets to optional unions.
79pub trait WriteAsOptionalUnion<T: ?Sized> {
80    #[doc(hidden)]
81    fn prepare(&self, builder: &mut Builder) -> Option<UnionOffset<T>>;
82}
83
84#[doc(hidden)]
85pub trait WriteAsPrimitive<P> {
86    fn write<const N: usize>(&self, cursor: Cursor<'_, N>, buffer_position: u32);
87}
88
89#[doc(hidden)]
90pub trait TableRead<'buf>: Sized {
91    fn from_buffer(
92        buffer: SliceWithStartOffset<'buf>,
93        offset: usize,
94    ) -> core::result::Result<Self, ErrorKind>;
95}
96
97#[doc(hidden)]
98pub trait TableReadUnion<'buf>: Sized {
99    fn from_buffer(
100        buffer: SliceWithStartOffset<'buf>,
101        offset: usize,
102        tag: u8,
103    ) -> core::result::Result<Self, ErrorKind>;
104}
105
106/// Trait used by generated code to read elements from vectors.
107pub trait VectorRead<'buf> {
108    #[doc(hidden)]
109    const STRIDE: usize;
110    #[doc(hidden)]
111    unsafe fn from_buffer(buffer: SliceWithStartOffset<'buf>, offset: usize) -> Self;
112}
113
114/// This trait is a hack to get around the coherence restriction.
115/// Ideally we would want to be able to do an `impl VectorRead<'buf> for planus::Result<MyType>`
116/// in our generated code, however instead we do something like this:
117///   impl<T: VectorReadInner<'buf>, E> VectorRead<'buf> for Result<T, E>
118#[doc(hidden)]
119pub trait VectorReadInner<'buf>: Sized {
120    #[doc(hidden)]
121    type Error: Sized;
122    #[doc(hidden)]
123    const STRIDE: usize;
124    #[doc(hidden)]
125    unsafe fn from_buffer(
126        buffer: SliceWithStartOffset<'buf>,
127        offset: usize,
128    ) -> core::result::Result<Self, Self::Error>;
129}
130
131/// Trait used by generated code to write elements to vectors.
132pub trait VectorWrite<P> {
133    #[doc(hidden)]
134    const STRIDE: usize;
135    #[doc(hidden)]
136    type Value: WriteAsPrimitive<P> + Sized;
137    #[doc(hidden)]
138    fn prepare(&self, builder: &mut Builder) -> Self::Value;
139    #[doc(hidden)]
140    unsafe fn write_values(
141        values: &[Self::Value],
142        bytes: *mut MaybeUninit<u8>,
143        buffer_position: u32,
144    );
145}