1use std::ops::Deref;
2
3mod codec;
4pub use codec::*;
5
6include!(concat!(env!("OUT_DIR"), "/table.rs"));
7
8#[derive(Debug, Clone, thiserror::Error)]
9pub enum Error {
10 #[error(transparent)]
11 Varint(#[from] unsigned_varint::decode::Error),
12
13 #[error("unexpected codec {0}")]
14 UnexpectedCodec(u64),
15
16 #[error("invalid data")]
17 InvalidData,
18}
19
20pub struct MultiEncoded([u8]);
22
23impl MultiEncoded {
24 #[inline(always)]
32 pub fn new(bytes: &[u8]) -> Result<&Self, Error> {
33 unsigned_varint::decode::u64(bytes)?;
34 Ok(unsafe { std::mem::transmute::<&[u8], &Self>(bytes) })
35 }
36
37 #[inline(always)]
48 pub unsafe fn new_unchecked(bytes: &[u8]) -> &Self {
49 unsafe { std::mem::transmute(bytes) }
50 }
51
52 #[allow(clippy::len_without_is_empty)]
53 pub fn len(&self) -> usize {
54 self.0.len()
55 }
56
57 #[inline(always)]
58 pub fn parts(&self) -> (u64, &[u8]) {
59 unsigned_varint::decode::u64(&self.0).unwrap()
60 }
61
62 #[inline(always)]
63 pub fn codec(&self) -> u64 {
64 self.parts().0
65 }
66
67 #[inline(always)]
68 pub fn data(&self) -> &[u8] {
69 self.parts().1
70 }
71
72 #[inline(always)]
74 pub fn as_bytes(&self) -> &[u8] {
75 &self.0
76 }
77
78 #[inline(always)]
79 pub fn decode<T: MultiCodec>(&self) -> Result<T, Error> {
80 let (codec, bytes) = self.parts();
81 T::from_codec_and_bytes(codec, bytes)
82 }
83}
84
85#[derive(Clone)]
86pub struct MultiEncodedBuf(Vec<u8>);
87
88impl MultiEncodedBuf {
89 #[inline(always)]
97 pub fn new(bytes: Vec<u8>) -> Result<Self, Error> {
98 unsigned_varint::decode::u64(&bytes)?;
99 Ok(Self(bytes))
100 }
101
102 pub fn encode_bytes(codec: u64, bytes: &[u8]) -> Self {
103 let mut codec_buffer = [0u8; 10];
104 let encoded_codec = unsigned_varint::encode::u64(codec, &mut codec_buffer);
105 let mut result = Vec::with_capacity(encoded_codec.len() + bytes.len());
106 result.extend(encoded_codec);
107 result.extend(bytes);
108 Self(result)
109 }
110
111 pub fn encode<T: MultiCodec>(value: &T) -> Self {
112 let (codec, bytes) = value.to_codec_and_bytes();
113 Self::encode_bytes(codec, &bytes)
114 }
115
116 #[inline(always)]
127 pub unsafe fn new_unchecked(bytes: Vec<u8>) -> Self {
128 Self(bytes)
129 }
130
131 #[inline(always)]
132 pub fn as_multi_encoded(&self) -> &MultiEncoded {
133 unsafe { MultiEncoded::new_unchecked(&self.0) }
134 }
135
136 #[inline(always)]
138 pub fn into_bytes(self) -> Vec<u8> {
139 self.0
140 }
141}
142
143impl Deref for MultiEncodedBuf {
144 type Target = MultiEncoded;
145
146 fn deref(&self) -> &Self::Target {
147 self.as_multi_encoded()
148 }
149}
150
151impl AsRef<[u8]> for MultiEncodedBuf {
152 fn as_ref(&self) -> &[u8] {
153 self.as_bytes()
154 }
155}