messagepack_core/decode/
str.rs1use super::{DecodeBorrowed, Error, NbyteReader};
4use crate::{Decode, formats::Format, io::IoRead};
5
6pub struct StrDecoder;
8
9impl<'de> DecodeBorrowed<'de> for StrDecoder {
10 type Value = &'de str;
11
12 fn decode_borrowed_with_format<R>(
13 format: Format,
14 reader: &mut R,
15 ) -> core::result::Result<Self::Value, Error<R::Error>>
16 where
17 R: IoRead<'de>,
18 {
19 let str_ref = ReferenceStrDecoder::decode_with_format(format, reader)?;
20 match str_ref {
21 ReferenceStr::Borrowed(s) => Ok(s),
22 ReferenceStr::Copied(_) => Err(Error::InvalidData),
23 }
24 }
25}
26
27impl<'de> DecodeBorrowed<'de> for &'de str {
28 type Value = &'de str;
29
30 fn decode_borrowed_with_format<R>(
31 format: Format,
32 reader: &mut R,
33 ) -> core::result::Result<Self::Value, Error<R::Error>>
34 where
35 R: IoRead<'de>,
36 {
37 StrDecoder::decode_borrowed_with_format(format, reader)
38 }
39}
40
41pub enum ReferenceStr<'de, 'a> {
43 Borrowed(&'de str),
45 Copied(&'a str),
47}
48
49pub struct ReferenceStrDecoder;
51
52impl<'de> Decode<'de> for ReferenceStrDecoder {
53 type Value<'a>
54 = ReferenceStr<'de, 'a>
55 where
56 Self: 'a,
57 'de: 'a;
58 fn decode_with_format<'a, R>(
59 format: Format,
60 reader: &'a mut R,
61 ) -> Result<Self::Value<'a>, Error<R::Error>>
62 where
63 R: IoRead<'de>,
64 'de: 'a,
65 {
66 let len = match format {
67 Format::FixStr(n) => n.into(),
68 Format::Str8 => NbyteReader::<1>::read(reader)?,
69 Format::Str16 => NbyteReader::<2>::read(reader)?,
70 Format::Str32 => NbyteReader::<4>::read(reader)?,
71 _ => return Err(Error::UnexpectedFormat),
72 };
73 let data = reader.read_slice(len).map_err(Error::Io)?;
74 match data {
75 crate::io::Reference::Borrowed(items) => {
76 let s = str::from_utf8(items).map_err(|_| Error::InvalidData)?;
77 Ok(ReferenceStr::Borrowed(s))
78 }
79 crate::io::Reference::Copied(items) => {
80 let s = str::from_utf8(items).map_err(|_| Error::InvalidData)?;
81 Ok(ReferenceStr::Copied(s))
82 }
83 }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use crate::decode::Decode;
91
92 #[test]
93 fn decode_str() {
94 let buf: &[u8] = &[
95 0xab, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64,
96 ];
97
98 let mut r = crate::io::SliceReader::new(buf);
99 let decoded = StrDecoder::decode(&mut r).unwrap();
100 let expect = "Hello World";
101 assert_eq!(decoded, expect);
102 assert_eq!(r.rest().len(), 0);
103 }
104
105 #[test]
106 fn decode_invalid_str() {
107 let buf: &[u8] = &[0xa2, 0xc3, 0x28];
108 let mut r = crate::io::SliceReader::new(buf);
109 let err = StrDecoder::decode(&mut r).unwrap_err();
110 assert_eq!(err, Error::InvalidData);
111
112 let buf: &[u8] = &[0xa1, 0x80];
113 let mut r = crate::io::SliceReader::new(buf);
114 let err = StrDecoder::decode(&mut r).unwrap_err();
115 assert_eq!(err, Error::InvalidData);
116 }
117}