flatbuffers_retained/
lib.rs

1//! This library allows you to validate Flatbuffer buffers once
2//! at initialization time then safely use them, unchecked, later.
3
4use flatbuffers::{Follow, InvalidFlatbuffer, Verifiable};
5
6mod flatbuffer_retained;
7mod size_prefixed;
8pub use flatbuffer_retained::FlatbufferRetained;
9pub use size_prefixed::SizePrefixedFlatbufferRetained;
10
11#[derive(Debug, Clone)]
12pub enum Retained<'a, T: Follow<'a>> {
13    Unprefixed(FlatbufferRetained<'a, T>),
14    SizePrefixed(SizePrefixedFlatbufferRetained<'a, T>),
15}
16impl<'a, T> Retained<'a, T>
17where
18    T: Follow<'a> + Verifiable,
19{
20    /// Make a new FlatbufferRetained class of type T from
21    /// an unprefixed byte buffer.
22    ///
23    /// # Arguments
24    ///
25    /// * `data` - The data that represents a flatbuffer of type T.
26    ///            not prefixed by size.
27    ///
28    /// # Errors
29    ///
30    /// May return any InvalidFlatbuffer error from run_verifier
31    /// when it parses the data.
32    pub fn new_unprefixed(data: Vec<u8>) -> Result<Self, InvalidFlatbuffer> {
33        Ok(Retained::Unprefixed(FlatbufferRetained::<T>::new(data)?))
34    }
35    /// Make a new FlatbufferRetained class of type T from
36    /// a size-prefixed byte buffer.
37    ///
38    /// # Arguments
39    ///
40    /// * `data` - The data that represents a flatbuffer of type T,
41    ///            prefixed by size.
42    ///
43    /// # Errors
44    ///
45    /// May return any InvalidFlatbuffer error from run_verifier
46    /// when it parses the data.
47    pub fn new_size_prefixed(data: Vec<u8>) -> Result<Self, InvalidFlatbuffer> {
48        Ok(Retained::SizePrefixed(
49            SizePrefixedFlatbufferRetained::<T>::new(data)?,
50        ))
51    }
52
53    /// Return a valid root of type T from the flatbuffer
54    /// buffer stored in self.
55    pub fn get(&'a self) -> <T as Follow<'a>>::Inner {
56        match self {
57            Retained::Unprefixed(ref a) => a.get(),
58            Retained::SizePrefixed(ref a) => a.get(),
59        }
60    }
61}
62impl<'a, T: Follow<'a>> Retained<'a, T> {
63    /// Return an iterator to traverse over the contained Vec.
64    pub fn iter(&self) -> std::slice::Iter<u8> {
65        match self {
66            Retained::Unprefixed(a) => a.iter(),
67            Retained::SizePrefixed(a) => a.iter(),
68        }
69    }
70
71    /// Deconstruct this class and return the Vec that
72    /// made up the data within it.
73    pub fn take(self) -> Vec<u8> {
74        match self {
75            Retained::Unprefixed(a) => a.take(),
76            Retained::SizePrefixed(a) => a.take(),
77        }
78    }
79
80    /// Return a reference to the Vec that make up the data within.
81    pub fn as_vec(&self) -> &Vec<u8> {
82        match self {
83            Retained::Unprefixed(a) => a.as_vec(),
84            Retained::SizePrefixed(a) => a.as_vec(),
85        }
86    }
87}
88
89impl<'a, T: Follow<'a>> Into<Vec<u8>> for Retained<'a, T> {
90    fn into(self) -> Vec<u8> {
91        match self {
92            Retained::Unprefixed(a) => a.take(),
93            Retained::SizePrefixed(a) => a.take(),
94        }
95    }
96}
97
98impl<'a, 'b, T: Follow<'a>> Into<&'b [u8]> for &'b Retained<'a, T> {
99    fn into(self) -> &'b [u8] {
100        match self {
101            &Retained::Unprefixed(ref a) => a.into(),
102            &Retained::SizePrefixed(ref a) => a.into(),
103        }
104    }
105}
106
107impl<'a, T: Follow<'a>> AsRef<[u8]> for Retained<'a, T> {
108    fn as_ref(&self) -> &[u8] {
109        match self {
110            &Retained::Unprefixed(ref a) => a.as_ref(),
111            &Retained::SizePrefixed(ref a) => a.as_ref(),
112        }
113    }
114}
115
116impl<'a, T: Follow<'a>> std::borrow::Borrow<[u8]> for Retained<'a, T> {
117    fn borrow(&self) -> &[u8] {
118        match self {
119            &Retained::Unprefixed(ref a) => a.borrow(),
120            &Retained::SizePrefixed(ref a) => a.borrow(),
121        }
122    }
123}
124
125impl<'a, T: Follow<'a>> std::ops::Deref for Retained<'a, T> {
126    type Target = [u8];
127    fn deref(&self) -> &[u8] {
128        match self {
129            &Retained::Unprefixed(ref a) => a.deref(),
130            &Retained::SizePrefixed(ref a) => a.deref(),
131        }
132    }
133}
134
135impl<'a, T: Follow<'a>> IntoIterator for Retained<'a, T> {
136    type Item = u8;
137    type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
138    fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter {
139        match self {
140            Retained::Unprefixed(a) => a.into_iter(),
141            Retained::SizePrefixed(a) => a.into_iter(),
142        }
143    }
144}