messagepack_core/encode/
bin.rs1use super::{Encode, Error, Result};
4use crate::{formats::Format, io::IoWrite};
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
8pub struct BinaryEncoder<'blob>(pub &'blob [u8]);
9
10impl<'blob> core::ops::Deref for BinaryEncoder<'blob> {
11 type Target = &'blob [u8];
12 fn deref(&self) -> &Self::Target {
13 &self.0
14 }
15}
16
17impl Encode for BinaryEncoder<'_> {
18 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
19 let self_len = self.len();
20 let format_len = match self_len {
21 0x00..=0xff => {
22 let cast = self_len as u8;
23 writer.write(&[Format::Bin8.as_byte(), cast])?;
24 Ok(2)
25 }
26 0x100..=0xffff => {
27 let cast = (self_len as u16).to_be_bytes();
28 writer.write(&[Format::Bin16.as_byte(), cast[0], cast[1]])?;
29 Ok(3)
30 }
31 0x10000..=0xffffffff => {
32 let cast = (self_len as u32).to_be_bytes();
33 writer.write(&[Format::Bin32.as_byte(), cast[0], cast[1], cast[2], cast[3]])?;
34
35 Ok(5)
36 }
37 _ => Err(Error::InvalidFormat),
38 }?;
39
40 writer.write(self.0)?;
41 Ok(format_len + self_len)
42 }
43}
44
45pub trait EncodeBytes {
47 fn encode_bytes<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error>;
49}
50
51impl EncodeBytes for &[u8] {
52 fn encode_bytes<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
53 BinaryEncoder(self).encode(writer)
54 }
55}
56
57impl<const N: usize> EncodeBytes for [u8; N] {
58 fn encode_bytes<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
59 self.as_slice().encode_bytes(writer)
60 }
61}
62
63impl<T> EncodeBytes for Option<T>
64where
65 T: EncodeBytes,
66{
67 fn encode_bytes<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
68 match self {
69 Some(value) => value.encode_bytes(writer),
70 None => ().encode(writer),
71 }
72 }
73}
74
75#[cfg(feature = "alloc")]
76mod alloc_impl {
77 use super::*;
78
79 impl EncodeBytes for alloc::vec::Vec<u8> {
80 fn encode_bytes<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
81 self.as_slice().encode_bytes(writer)
82 }
83 }
84
85 impl EncodeBytes for alloc::boxed::Box<[u8]> {
86 fn encode_bytes<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
87 self.as_ref().encode_bytes(writer)
88 }
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use rstest::rstest;
96
97 #[rstest]
98 #[case(0xc4, 255_u8.to_be_bytes(),[0x12;255])]
99 #[case(0xc5, 65535_u16.to_be_bytes(),[0x34;65535])]
100 #[case(0xc6, 65536_u32.to_be_bytes(),[0x56;65536])]
101 fn encode_str_sized<S: AsRef<[u8]>, D: AsRef<[u8]>>(
102 #[case] marker: u8,
103 #[case] size: S,
104 #[case] data: D,
105 ) {
106 let expected = marker
107 .to_be_bytes()
108 .iter()
109 .chain(size.as_ref())
110 .chain(data.as_ref())
111 .cloned()
112 .collect::<Vec<u8>>();
113
114 let encoder = BinaryEncoder(data.as_ref());
115
116 let mut buf = vec![];
117 let n = encoder.encode(&mut buf).unwrap();
118
119 assert_eq!(&buf, &expected);
120 assert_eq!(n, expected.len());
121 }
122}