flatbuffers_retained/
flatbuffer_retained.rs

1//! This module focuses on validation and storage of flatbuffers
2//! without size-prefixes. It allows validation of Flatbuffer buffers
3//! once at initialization time then safely use them, unchecked, later.
4
5use flatbuffers::{
6    root_unchecked, Follow, ForwardsUOffset, InvalidFlatbuffer, Verifiable, Verifier,
7    VerifierOptions,
8};
9use std::marker::PhantomData;
10
11/// This struct holds data backing an unprefixed flatbuffer.
12/// It is not possible to create this struct without a valid
13/// flatbuffer of type T.
14#[derive(Clone, Debug)]
15pub struct FlatbufferRetained<'a, T>
16where
17    T: Follow<'a>,
18{
19    /// Data represting a validated T.
20    data: Vec<u8>,
21    /// Phantom data to place-hold which T data was validated for.
22    phantom: PhantomData<&'a T>,
23}
24
25impl<'a, T> FlatbufferRetained<'a, T>
26where
27    T: Follow<'a> + Verifiable,
28{
29    /// Make a new FlatbufferRetained class of type T from
30    /// an unprefixed byte buffer.
31    ///
32    /// # Arguments
33    ///
34    /// * `data` - The data that represents a flatbuffer of type T.
35    ///            not prefixed by size.
36    ///
37    /// # Errors
38    ///
39    /// May return any InvalidFlatbuffer error from run_verifier
40    /// when it parses the data.
41    pub fn new(data: Vec<u8>) -> Result<Self, InvalidFlatbuffer> {
42        let opts = VerifierOptions::default();
43        let mut v = Verifier::new(&opts, &data);
44        <ForwardsUOffset<T>>::run_verifier(&mut v, 0)?;
45        Ok(FlatbufferRetained {
46            data,
47            phantom: PhantomData::default(),
48        })
49    }
50
51    /// Return a valid root of type T from the flatbuffer
52    /// buffer stored in self.
53    pub fn get(&'a self) -> <T as Follow<'a>>::Inner {
54        unsafe { root_unchecked::<T>(&self.data) }
55    }
56}
57
58impl<'a, T: Follow<'a>> FlatbufferRetained<'a, T> {
59    /// Return an iterator to traverse over the contained Vec.
60    pub fn iter(&self) -> std::slice::Iter<u8> {
61        self.data.iter()
62    }
63
64    /// Deconstruct this class and return the Vec that
65    /// made up the data within it.
66    pub fn take(self) -> Vec<u8> {
67        self.data
68    }
69
70    /// Return a reference to the Vec that make up the data within.
71    pub fn as_vec(&self) -> &Vec<u8> {
72        &self.data
73    }
74}
75
76impl<'a, T: Follow<'a>> Into<Vec<u8>> for FlatbufferRetained<'a, T> {
77    fn into(self) -> Vec<u8> {
78        self.take()
79    }
80}
81
82impl<'a, 'b, T: Follow<'a>> Into<&'b Vec<u8>> for &'b FlatbufferRetained<'a, T> {
83    fn into(self) -> &'b Vec<u8> {
84        &self.data
85    }
86}
87
88impl<'a, 'b, T: Follow<'a>> Into<&'b [u8]> for &'b FlatbufferRetained<'a, T> {
89    fn into(self) -> &'b [u8] {
90        &self.data[..]
91    }
92}
93
94impl<'a, T: Follow<'a>> AsRef<[u8]> for FlatbufferRetained<'a, T> {
95    fn as_ref(&self) -> &[u8] {
96        self.data.as_ref()
97    }
98}
99
100impl<'a, T: Follow<'a>> AsRef<Vec<u8>> for FlatbufferRetained<'a, T> {
101    fn as_ref(&self) -> &Vec<u8> {
102        &self.data
103    }
104}
105
106impl<'a, T: Follow<'a>> std::borrow::Borrow<[u8]> for FlatbufferRetained<'a, T> {
107    fn borrow(&self) -> &[u8] {
108        self.data.borrow()
109    }
110}
111
112impl<'a, T: Follow<'a>> std::ops::Deref for FlatbufferRetained<'a, T> {
113    type Target = [u8];
114    fn deref(&self) -> &[u8] {
115        self.data.deref()
116    }
117}
118
119impl<'a, T: Follow<'a>> IntoIterator for FlatbufferRetained<'a, T> {
120    type Item = u8;
121    type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
122    fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter {
123        self.data.into_iter()
124    }
125}