aldrin_core/
message_serializer.rs

1use crate::buf_ext::BufMutExt;
2use crate::message::MessageKind;
3use crate::serialized_value::SerializedValue;
4use bytes::{BufMut, BytesMut};
5use thiserror::Error;
6use uuid::Uuid;
7
8pub(crate) struct MessageSerializer {
9    buf: BytesMut,
10}
11
12impl MessageSerializer {
13    pub fn without_value(kind: MessageKind) -> Self {
14        debug_assert!(!kind.has_value());
15
16        let mut buf = BytesMut::zeroed(4);
17        buf.put_u8(kind.into());
18
19        Self { buf }
20    }
21
22    pub fn with_value(
23        value: SerializedValue,
24        kind: MessageKind,
25    ) -> Result<Self, MessageSerializeError> {
26        debug_assert!(kind.has_value());
27
28        let mut buf = value.into_bytes_mut();
29
30        // 4 bytes message length + 1 byte message kind + 4 bytes value length + at least 1 byte
31        // value.
32        if buf.len() < 10 {
33            return Err(MessageSerializeError::InvalidValue);
34        }
35
36        let value_len = buf.len() - 9;
37        if value_len > u32::MAX as usize {
38            return Err(MessageSerializeError::Overflow);
39        }
40
41        buf[4] = kind.into();
42        buf[5..9].copy_from_slice(&(value_len as u32).to_le_bytes());
43
44        Ok(Self { buf })
45    }
46
47    pub fn with_none_value(kind: MessageKind) -> Self {
48        Self::with_value(SerializedValue::serialize(&()).unwrap(), kind).unwrap()
49    }
50
51    pub fn put_discriminant_u8(&mut self, discriminant: impl Into<u8>) {
52        self.buf.put_discriminant_u8(discriminant);
53    }
54
55    pub fn put_varint_u32_le(&mut self, n: u32) {
56        self.buf.put_varint_u32_le(n);
57    }
58
59    pub fn put_uuid(&mut self, uuid: Uuid) {
60        self.buf.put_slice(uuid.as_ref());
61    }
62
63    pub fn finish(mut self) -> Result<BytesMut, MessageSerializeError> {
64        let len = self.buf.len();
65        if len <= u32::MAX as usize {
66            self.buf[..4].copy_from_slice(&(len as u32).to_le_bytes());
67            Ok(self.buf)
68        } else {
69            Err(MessageSerializeError::Overflow)
70        }
71    }
72}
73
74#[derive(Error, Debug, Copy, Clone, PartialEq, Eq)]
75pub enum MessageSerializeError {
76    #[error("serialized message overflowed")]
77    Overflow,
78
79    #[error("invalid value")]
80    InvalidValue,
81}