messagepack_core/encode/
str.rs

1use 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}