xref: /aosp_15_r20/external/flatbuffers/rust/flexbuffers/src/buffer.rs (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Worker use std::ops::{Deref, Range};
2*890232f2SAndroid Build Coastguard Worker 
3*890232f2SAndroid Build Coastguard Worker /// The underlying buffer that is used by a flexbuffer Reader.
4*890232f2SAndroid Build Coastguard Worker ///
5*890232f2SAndroid Build Coastguard Worker /// This allows for custom buffer implementations as long as they can be viewed as a &[u8].
6*890232f2SAndroid Build Coastguard Worker pub trait Buffer: Deref<Target = [u8]> + Sized {
7*890232f2SAndroid Build Coastguard Worker     // The `BufferString` allows for a buffer to return a custom string which will have the
8*890232f2SAndroid Build Coastguard Worker     // lifetime of the underlying buffer. A simple `std::str::from_utf8` wouldn't work since that
9*890232f2SAndroid Build Coastguard Worker     // returns a &str, which is then owned by the callee (cannot be returned from a function).
10*890232f2SAndroid Build Coastguard Worker     //
11*890232f2SAndroid Build Coastguard Worker     // Example: During deserialization a `BufferString` is returned, allowing the deserializer
12*890232f2SAndroid Build Coastguard Worker     // to "borrow" the given str - b/c there is a "lifetime" guarantee, so to speak, from the
13*890232f2SAndroid Build Coastguard Worker     // underlying buffer.
14*890232f2SAndroid Build Coastguard Worker     /// A BufferString which will live at least as long as the Buffer itself.
15*890232f2SAndroid Build Coastguard Worker     ///
16*890232f2SAndroid Build Coastguard Worker     /// Deref's to UTF-8 `str`, and only generated from the `buffer_str` function Result.
17*890232f2SAndroid Build Coastguard Worker     type BufferString: Deref<Target = str> + Sized + serde::ser::Serialize;
18*890232f2SAndroid Build Coastguard Worker 
19*890232f2SAndroid Build Coastguard Worker     /// This method returns an instance of type Self. This allows for lifetimes to be tracked
20*890232f2SAndroid Build Coastguard Worker     /// in cases of deserialization.
21*890232f2SAndroid Build Coastguard Worker     ///
22*890232f2SAndroid Build Coastguard Worker     /// It also lets custom buffers manage reference counts.
23*890232f2SAndroid Build Coastguard Worker     ///
24*890232f2SAndroid Build Coastguard Worker     /// Returns None if:
25*890232f2SAndroid Build Coastguard Worker     /// - range start is greater than end
26*890232f2SAndroid Build Coastguard Worker     /// - range end is out of bounds
27*890232f2SAndroid Build Coastguard Worker     ///
28*890232f2SAndroid Build Coastguard Worker     /// This operation should be fast -> O(1), ideally with no heap allocations.
slice(&self, range: Range<usize>) -> Option<Self>29*890232f2SAndroid Build Coastguard Worker     fn slice(&self, range: Range<usize>) -> Option<Self>;
30*890232f2SAndroid Build Coastguard Worker 
31*890232f2SAndroid Build Coastguard Worker     /// Creates a shallow copy of the given buffer, similar to `slice`.
32*890232f2SAndroid Build Coastguard Worker     ///
33*890232f2SAndroid Build Coastguard Worker     /// This operation should be fast -> O(1), ideally with no heap allocations.
34*890232f2SAndroid Build Coastguard Worker     #[inline]
shallow_copy(&self) -> Self35*890232f2SAndroid Build Coastguard Worker     fn shallow_copy(&self) -> Self {
36*890232f2SAndroid Build Coastguard Worker         self.slice(0..self.len()).unwrap()
37*890232f2SAndroid Build Coastguard Worker     }
38*890232f2SAndroid Build Coastguard Worker 
39*890232f2SAndroid Build Coastguard Worker     /// Creates an empty instance of a `Buffer`. This is different than `Default` b/c it
40*890232f2SAndroid Build Coastguard Worker     /// guarantees that the buffer instance will have length zero.
41*890232f2SAndroid Build Coastguard Worker     ///
42*890232f2SAndroid Build Coastguard Worker     /// Most impls shold be able to implement this via `Default`.
empty() -> Self43*890232f2SAndroid Build Coastguard Worker     fn empty() -> Self;
44*890232f2SAndroid Build Coastguard Worker 
45*890232f2SAndroid Build Coastguard Worker     /// Based off of the `empty` function, allows override for optimization purposes.
46*890232f2SAndroid Build Coastguard Worker     #[inline]
empty_str() -> Self::BufferString47*890232f2SAndroid Build Coastguard Worker     fn empty_str() -> Self::BufferString {
48*890232f2SAndroid Build Coastguard Worker         Self::empty().buffer_str().unwrap()
49*890232f2SAndroid Build Coastguard Worker     }
50*890232f2SAndroid Build Coastguard Worker 
51*890232f2SAndroid Build Coastguard Worker     /// Attempts to convert the given buffer to a custom string type.
52*890232f2SAndroid Build Coastguard Worker     ///
53*890232f2SAndroid Build Coastguard Worker     /// This should fail if the type does not have valid UTF-8 bytes, and must be zero copy.
buffer_str(&self) -> Result<Self::BufferString, std::str::Utf8Error>54*890232f2SAndroid Build Coastguard Worker     fn buffer_str(&self) -> Result<Self::BufferString, std::str::Utf8Error>;
55*890232f2SAndroid Build Coastguard Worker }
56*890232f2SAndroid Build Coastguard Worker 
57*890232f2SAndroid Build Coastguard Worker impl<'de> Buffer for &'de [u8] {
58*890232f2SAndroid Build Coastguard Worker     type BufferString = &'de str;
59*890232f2SAndroid Build Coastguard Worker 
60*890232f2SAndroid Build Coastguard Worker     #[inline]
slice(&self, range: Range<usize>) -> Option<Self>61*890232f2SAndroid Build Coastguard Worker     fn slice(&self, range: Range<usize>) -> Option<Self> {
62*890232f2SAndroid Build Coastguard Worker         self.get(range)
63*890232f2SAndroid Build Coastguard Worker     }
64*890232f2SAndroid Build Coastguard Worker 
65*890232f2SAndroid Build Coastguard Worker     #[inline]
empty() -> Self66*890232f2SAndroid Build Coastguard Worker     fn empty() -> Self {
67*890232f2SAndroid Build Coastguard Worker         &[]
68*890232f2SAndroid Build Coastguard Worker     }
69*890232f2SAndroid Build Coastguard Worker 
70*890232f2SAndroid Build Coastguard Worker     /// Based off of the `empty` function, allows override for optimization purposes.
71*890232f2SAndroid Build Coastguard Worker     #[inline]
empty_str() -> Self::BufferString72*890232f2SAndroid Build Coastguard Worker     fn empty_str() -> Self::BufferString {
73*890232f2SAndroid Build Coastguard Worker         &""
74*890232f2SAndroid Build Coastguard Worker     }
75*890232f2SAndroid Build Coastguard Worker 
76*890232f2SAndroid Build Coastguard Worker     #[inline]
buffer_str(&self) -> Result<Self::BufferString, std::str::Utf8Error>77*890232f2SAndroid Build Coastguard Worker     fn buffer_str(&self) -> Result<Self::BufferString, std::str::Utf8Error> {
78*890232f2SAndroid Build Coastguard Worker         std::str::from_utf8(self)
79*890232f2SAndroid Build Coastguard Worker     }
80*890232f2SAndroid Build Coastguard Worker }
81