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