aldrin_core/
serialized_value.rs1#[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
18const MSG_HEADER_LEN: usize = 9;
20
21#[derive(Clone, Eq)]
22pub struct SerializedValue {
23 buf: BytesMut,
24}
25
26impl SerializedValue {
27 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
92impl 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 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}