aldrin_core/
message_serializer.rs1use 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 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}