aldrin_core/
serialized_value.rs

1#[cfg(test)]
2mod test;
3
4#[cfg(feature = "introspection")]
5use crate::introspection::{ir, Introspectable, LexicalId, References};
6use crate::tags::{self, PrimaryTag, Tag};
7use crate::{
8    convert_value, Deserialize, DeserializeError, DeserializePrimary, Deserializer,
9    ProtocolVersion, Serialize, SerializeError, SerializePrimary, Serializer, Value,
10    ValueConversionError, ValueKind,
11};
12use bytes::BytesMut;
13use std::borrow::{Borrow, Cow};
14use std::cmp::Ordering;
15use std::ops::Deref;
16use std::{fmt, mem};
17
18// 4 bytes message length + 1 byte message kind + 4 bytes value length.
19const MSG_HEADER_LEN: usize = 9;
20
21#[derive(Clone, Eq)]
22pub struct SerializedValue {
23    buf: BytesMut,
24}
25
26impl SerializedValue {
27    /// Cheaply creates an empty `SerializedValue`.
28    ///
29    /// Note that an empty `SerializedValue` will panic when derefencing it to a
30    /// [`SerializedValueSlice`] and when trying to deserialize it.
31    pub fn empty() -> Self {
32        Self {
33            buf: BytesMut::new(),
34        }
35    }
36
37    pub fn serialize_as<T: Tag>(value: impl Serialize<T>) -> Result<Self, SerializeError> {
38        let mut this = Self::new();
39
40        let serializer = Serializer::new(&mut this.buf, 0)?;
41        value.serialize(serializer)?;
42
43        Ok(this)
44    }
45
46    pub fn serialize(value: impl SerializePrimary) -> Result<Self, SerializeError> {
47        Self::serialize_as(value)
48    }
49
50    pub fn take(&mut self) -> Self {
51        mem::take(self)
52    }
53
54    pub fn convert(
55        &mut self,
56        from: Option<ProtocolVersion>,
57        to: ProtocolVersion,
58    ) -> Result<(), ValueConversionError> {
59        convert_value::convert_mut(self, from, to)
60    }
61
62    pub(crate) fn new() -> Self {
63        Self {
64            buf: BytesMut::zeroed(MSG_HEADER_LEN),
65        }
66    }
67
68    pub(crate) fn from_bytes_mut(buf: BytesMut) -> Self {
69        debug_assert!(buf.len() > MSG_HEADER_LEN);
70        Self { buf }
71    }
72
73    pub(crate) fn into_bytes_mut(self) -> BytesMut {
74        self.buf
75    }
76}
77
78impl Default for SerializedValue {
79    fn default() -> Self {
80        Self::empty()
81    }
82}
83
84impl Deref for SerializedValue {
85    type Target = SerializedValueSlice;
86
87    fn deref(&self) -> &SerializedValueSlice {
88        SerializedValueSlice::new(&self.buf[MSG_HEADER_LEN..])
89    }
90}
91
92// The default Debug implementation renders the bytes as ASCII or escape sequences, which isn't
93// particularly useful here.
94impl fmt::Debug for SerializedValue {
95    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96        f.debug_struct("SerializedValue")
97            .field("buf", &&*self.buf)
98            .finish()
99    }
100}
101
102impl AsRef<SerializedValueSlice> for SerializedValue {
103    fn as_ref(&self) -> &SerializedValueSlice {
104        self
105    }
106}
107
108impl Borrow<SerializedValueSlice> for SerializedValue {
109    fn borrow(&self) -> &SerializedValueSlice {
110        self
111    }
112}
113
114impl AsRef<[u8]> for SerializedValue {
115    fn as_ref(&self) -> &[u8] {
116        self
117    }
118}
119
120impl PartialEq for SerializedValue {
121    fn eq(&self, other: &Self) -> bool {
122        ***self == ***other
123    }
124}
125
126impl PartialEq<SerializedValueSlice> for SerializedValue {
127    fn eq(&self, other: &SerializedValueSlice) -> bool {
128        ***self == **other
129    }
130}
131
132impl PartialEq<[u8]> for SerializedValue {
133    fn eq(&self, other: &[u8]) -> bool {
134        ***self == *other
135    }
136}
137
138impl PartialEq<SerializedValue> for [u8] {
139    fn eq(&self, other: &SerializedValue) -> bool {
140        *self == ***other
141    }
142}
143
144impl PartialOrd for SerializedValue {
145    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
146        Some(self.cmp(other))
147    }
148}
149
150impl Ord for SerializedValue {
151    fn cmp(&self, other: &Self) -> Ordering {
152        (***self).cmp(&***other)
153    }
154}
155
156impl PartialOrd<SerializedValueSlice> for SerializedValue {
157    fn partial_cmp(&self, other: &SerializedValueSlice) -> Option<Ordering> {
158        (***self).partial_cmp(&**other)
159    }
160}
161
162impl PartialOrd<[u8]> for SerializedValue {
163    fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
164        (***self).partial_cmp(other)
165    }
166}
167
168impl PartialOrd<SerializedValue> for [u8] {
169    fn partial_cmp(&self, other: &SerializedValue) -> Option<Ordering> {
170        (*self).partial_cmp(&***other)
171    }
172}
173
174impl PrimaryTag for SerializedValue {
175    type Tag = tags::Value;
176}
177
178impl Serialize<tags::Value> for SerializedValue {
179    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
180        serializer.serialize(&self)
181    }
182}
183
184impl Serialize<tags::Value> for &SerializedValue {
185    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
186        serializer.serialize(&**self)
187    }
188}
189
190impl Deserialize<tags::Value> for SerializedValue {
191    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
192        deserializer
193            .split_off_serialized_value()
194            .map(SerializedValueSlice::to_owned)
195    }
196}
197
198#[cfg(feature = "introspection")]
199impl Introspectable for SerializedValue {
200    fn layout() -> ir::LayoutIr {
201        ir::BuiltInTypeIr::Value.into()
202    }
203
204    fn lexical_id() -> LexicalId {
205        LexicalId::VALUE
206    }
207
208    fn add_references(_references: &mut References) {}
209}
210
211#[cfg(feature = "fuzzing")]
212impl<'a> arbitrary::Arbitrary<'a> for SerializedValue {
213    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
214        let len = u.arbitrary_len::<u8>()?.max(1);
215        let bytes = u.bytes(len)?;
216
217        let mut buf = BytesMut::with_capacity(MSG_HEADER_LEN + len);
218        buf.resize(MSG_HEADER_LEN, 0);
219        buf.extend_from_slice(bytes);
220
221        Ok(Self::from_bytes_mut(buf))
222    }
223}
224
225#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
226#[repr(transparent)]
227pub struct SerializedValueSlice([u8]);
228
229impl SerializedValueSlice {
230    pub(crate) fn new<T: AsRef<[u8]> + ?Sized>(buf: &T) -> &Self {
231        let self_ptr = buf.as_ref() as *const [u8] as *const Self;
232        // Safe because of repr(transparent).
233        unsafe { &*self_ptr }
234    }
235
236    pub fn kind(&self) -> Result<ValueKind, DeserializeError> {
237        let mut buf = &self.0;
238        let deserializer = Deserializer::new(&mut buf, 0)?;
239        deserializer.peek_value_kind()
240    }
241
242    pub fn deserialize_as<T: Tag, U: Deserialize<T>>(&self) -> Result<U, DeserializeError> {
243        let mut buf = &self.0;
244        let deserializer = Deserializer::new(&mut buf, 0)?;
245
246        let res = U::deserialize(deserializer);
247
248        if res.is_ok() && !buf.is_empty() {
249            return Err(DeserializeError::TrailingData);
250        }
251
252        res
253    }
254
255    pub fn deserialize<T: DeserializePrimary>(&self) -> Result<T, DeserializeError> {
256        self.deserialize_as()
257    }
258
259    pub fn deserialize_as_value(&self) -> Result<Value, DeserializeError> {
260        self.deserialize()
261    }
262
263    pub fn convert(
264        &self,
265        from: Option<ProtocolVersion>,
266        to: ProtocolVersion,
267    ) -> Result<Cow<'_, Self>, ValueConversionError> {
268        convert_value::convert(self, from, to)
269    }
270}
271
272impl Deref for SerializedValueSlice {
273    type Target = [u8];
274
275    fn deref(&self) -> &[u8] {
276        &self.0
277    }
278}
279
280impl AsRef<[u8]> for SerializedValueSlice {
281    fn as_ref(&self) -> &[u8] {
282        self
283    }
284}
285
286impl ToOwned for SerializedValueSlice {
287    type Owned = SerializedValue;
288
289    fn to_owned(&self) -> SerializedValue {
290        let mut buf = BytesMut::with_capacity(MSG_HEADER_LEN + self.len());
291        buf.resize(MSG_HEADER_LEN, 0);
292        buf.extend_from_slice(self);
293
294        SerializedValue::from_bytes_mut(buf)
295    }
296}
297
298impl PartialEq<SerializedValue> for SerializedValueSlice {
299    fn eq(&self, other: &SerializedValue) -> bool {
300        **self == ***other
301    }
302}
303
304impl PartialEq<[u8]> for SerializedValueSlice {
305    fn eq(&self, other: &[u8]) -> bool {
306        **self == *other
307    }
308}
309
310impl PartialEq<SerializedValueSlice> for [u8] {
311    fn eq(&self, other: &SerializedValueSlice) -> bool {
312        *self == **other
313    }
314}
315
316impl PartialOrd<SerializedValue> for SerializedValueSlice {
317    fn partial_cmp(&self, other: &SerializedValue) -> Option<Ordering> {
318        (**self).partial_cmp(&***other)
319    }
320}
321
322impl PartialOrd<[u8]> for SerializedValueSlice {
323    fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
324        (**self).partial_cmp(other)
325    }
326}
327
328impl PartialOrd<SerializedValueSlice> for [u8] {
329    fn partial_cmp(&self, other: &SerializedValueSlice) -> Option<Ordering> {
330        (*self).partial_cmp(&**other)
331    }
332}
333
334impl PrimaryTag for &SerializedValueSlice {
335    type Tag = tags::Value;
336}
337
338impl Serialize<tags::Value> for &SerializedValueSlice {
339    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
340        serializer.copy_from_serialized_value(self)
341    }
342}
343
344#[cfg(feature = "introspection")]
345impl Introspectable for SerializedValueSlice {
346    fn layout() -> ir::LayoutIr {
347        ir::BuiltInTypeIr::Value.into()
348    }
349
350    fn lexical_id() -> LexicalId {
351        LexicalId::VALUE
352    }
353
354    fn add_references(_references: &mut References) {}
355}