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