messagepack_core/encode/
str.rs1use core::ops::Deref;
2
3use super::{Encode, Error, Result};
4use crate::{formats::Format, io::IoWrite};
5
6pub struct StrFormatEncoder(pub usize);
7impl<W: IoWrite> Encode<W> for StrFormatEncoder {
8 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
9 match self.0 {
10 0x00..=31 => {
11 let cast = self.0 as u8;
12 writer.write_bytes(&Format::FixStr(cast).as_slice())?;
13 Ok(1)
14 }
15 32..=0xff => {
16 let cast = self.0 as u8;
17 writer.write_bytes(&Format::Str8.as_slice())?;
18 writer.write_bytes(&cast.to_be_bytes())?;
19 Ok(2)
20 }
21 0x100..=0xffff => {
22 let cast = self.0 as u16;
23 writer.write_bytes(&Format::Str16.as_slice())?;
24 writer.write_bytes(&cast.to_be_bytes())?;
25 Ok(3)
26 }
27 0x10000..=0xffffffff => {
28 let cast = self.0 as u32;
29 writer.write_bytes(&Format::Str32.as_slice())?;
30 writer.write_bytes(&cast.to_be_bytes())?;
31 Ok(5)
32 }
33 _ => Err(Error::InvalidFormat),
34 }
35 }
36}
37
38pub struct StrDataEncoder<'a>(pub &'a str);
39impl<W: IoWrite> Encode<W> for StrDataEncoder<'_> {
40 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
41 let data = self.0.as_bytes();
42 writer.write_bytes(data)?;
43 Ok(self.0.len())
44 }
45}
46pub struct StrEncoder<'s>(pub &'s str);
47
48impl<'s> Deref for StrEncoder<'s> {
49 type Target = &'s str;
50
51 fn deref(&self) -> &Self::Target {
52 &self.0
53 }
54}
55
56impl<W: IoWrite> Encode<W> for StrEncoder<'_> {
57 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
58 let self_len = self.len();
59 let format_len = StrFormatEncoder(self_len).encode(writer)?;
60 let data_len = StrDataEncoder(self.0).encode(writer)?;
61
62 Ok(format_len + data_len)
63 }
64}
65
66impl<W: IoWrite> Encode<W> for &str {
67 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
68 StrEncoder(self).encode(writer)
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use rstest::rstest;
76
77 #[rstest]
78 #[case("Today",[0xa5, 0x54, 0x6f, 0x64, 0x61, 0x79])]
79 #[case("MessagePack",[0xab,0x4d,0x65,0x73,0x73,0x61,0x67,0x65,0x50,0x61,0x63,0x6b])]
80 fn encode_fixed_str<E: AsRef<[u8]> + Sized>(#[case] value: &str, #[case] expected: E) {
81 let expected = expected.as_ref();
82 let encoder = StrEncoder(value);
83
84 let mut buf = vec![];
85 let n = encoder.encode(&mut buf).unwrap();
86 assert_eq!(buf, expected);
87 assert_eq!(n, expected.len());
88 }
89
90 #[rstest]
91 #[case(0xd9, 255_u8.to_be_bytes(),255)]
92 #[case(0xda, 65535_u16.to_be_bytes(),65535)]
93 #[case(0xdb, 65536_u32.to_be_bytes(),65536)]
94 fn encode_str_sized<L: AsRef<[u8]>>(#[case] marker: u8, #[case] size: L, #[case] len: usize) {
95 let value = core::iter::repeat_n("a", len).collect::<String>();
96 let expected = marker
97 .to_be_bytes()
98 .iter()
99 .chain(size.as_ref())
100 .cloned()
101 .chain(value.chars().map(|c| c as u8))
102 .collect::<Vec<u8>>();
103
104 let encoder = StrEncoder(&value);
105
106 let mut buf = vec![];
107 let n = encoder.encode(&mut buf).unwrap();
108
109 assert_eq!(&buf, &expected);
110 assert_eq!(n, expected.len());
111 }
112}