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