messagepack_core/decode/
str.rs

1//! String decoding helpers.
2
3use super::{Decode, Error, NbyteReader, Result};
4use crate::formats::Format;
5
6/// Decode a MessagePack string and return a borrowed `&str`.
7pub struct StrDecoder;
8
9impl<'a> Decode<'a> for StrDecoder {
10    type Value = &'a str;
11    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
12        let (format, buf) = Format::decode(buf)?;
13        match format {
14            Format::FixStr(_) | Format::Str8 | Format::Str16 | Format::Str32 => {
15                Self::decode_with_format(format, buf)
16            }
17            _ => Err(Error::UnexpectedFormat),
18        }
19    }
20
21    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
22        let (len, buf) = match format {
23            Format::FixStr(n) => (n.into(), buf),
24            Format::Str8 => NbyteReader::<1>::read(buf)?,
25            Format::Str16 => NbyteReader::<2>::read(buf)?,
26            Format::Str32 => NbyteReader::<4>::read(buf)?,
27            _ => return Err(Error::UnexpectedFormat),
28        };
29        let (data, rest) = buf.split_at_checked(len).ok_or(Error::EofData)?;
30        let s = core::str::from_utf8(data).map_err(|_| Error::InvalidData)?;
31        Ok((s, rest))
32    }
33}
34
35impl<'a> Decode<'a> for &'a str {
36    type Value = &'a str;
37
38    fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
39        StrDecoder::decode(buf)
40    }
41
42    fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
43        StrDecoder::decode_with_format(format, buf)
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn decode_str() {
53        let buf: &[u8] = &[
54            0xab, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64,
55        ];
56
57        let (decoded, rest) = StrDecoder::decode(buf).unwrap();
58        let expect = "Hello World";
59        assert_eq!(decoded, expect);
60        assert_eq!(rest.len(), 0);
61    }
62
63    #[test]
64    fn decode_invalid_str() {
65        let buf: &[u8] = &[0xa2, 0xc3, 0x28];
66        let err = StrDecoder::decode(buf).unwrap_err();
67        assert_eq!(err, Error::InvalidData);
68
69        let buf: &[u8] = &[0xa1, 0x80];
70        let err = StrDecoder::decode(buf).unwrap_err();
71        assert_eq!(err, Error::InvalidData);
72    }
73}