Skip to main content

librqbit_bencode/
deserialize.rs

1use std::marker::PhantomData;
2
3use arrayvec::ArrayVec;
4use atoi::{FromRadix10, FromRadix10Signed};
5use buffers::ByteBuf;
6use clone_to_owned::CloneToOwned;
7use serde::{Deserialize, Serialize, forward_to_deserialize_any};
8
9use crate::raw_value::TAG;
10
11pub struct BencodeDeserializer<'de> {
12    buf: &'de [u8],
13    field_context: ErrorContext<'de>,
14    field_context_did_not_fit: u8,
15    parsing_key: bool,
16}
17
18impl<'de> BencodeDeserializer<'de> {
19    pub fn new_from_buf(buf: &'de [u8]) -> BencodeDeserializer<'de> {
20        Self {
21            buf,
22            field_context: Default::default(),
23            field_context_did_not_fit: 0,
24            parsing_key: false,
25        }
26    }
27
28    pub fn into_remaining(self) -> &'de [u8] {
29        self.buf
30    }
31
32    #[inline]
33    pub fn parse_first_byte(&mut self, c: u8, err: Error) -> Result<(), Error> {
34        match self.buf.first() {
35            Some(start) if *start == c => {
36                self.buf = &self.buf[1..];
37                Ok(())
38            }
39            Some(_) => Err(err),
40            None => Err(Error::Eof),
41        }
42    }
43
44    fn parse_integer<I>(&mut self, atoi: impl Fn(&'de [u8]) -> (I, usize)) -> Result<I, Error> {
45        self.parse_first_byte(b'i', Error::InvalidValue)?;
46        match atoi(self.buf) {
47            (v, len) if len > 0 && self.buf.get(len) == Some(&b'e') => {
48                self.buf = &self.buf[len + 1..];
49                Ok(v)
50            }
51            _ => Err(Error::InvalidValue),
52        }
53    }
54
55    fn parse_bytes(&mut self) -> Result<&'de [u8], Error> {
56        let b = match usize::from_radix_10(self.buf) {
57            (v, len) if len > 0 && self.buf.get(len) == Some(&b':') => {
58                self.buf = unsafe { self.buf.get_unchecked(len + 1..) };
59                let (bytes, rest) = self.buf.split_at_checked(v).ok_or(Error::Eof)?;
60                self.buf = rest;
61                bytes
62            }
63            _ => return Err(Error::InvalidValue),
64        };
65        if self.parsing_key && self.field_context.try_push(ByteBuf(b)).is_err() {
66            self.field_context_did_not_fit = self.field_context_did_not_fit.saturating_add(1);
67        }
68        Ok(b)
69    }
70}
71
72/// Deserialize a bencode value. If there are trailing bytes, will error.
73pub fn from_bytes<'a, T>(buf: &'a [u8]) -> Result<T, ErrorWithContext<'a>>
74where
75    T: serde::de::Deserialize<'a>,
76{
77    let (v, rest) = from_bytes_with_rest(buf)?;
78    if !rest.is_empty() {
79        return Err(ErrorWithContext {
80            kind: Error::BytesRemaining(rest.len()),
81            ctx: Default::default(),
82        });
83    }
84    Ok(v)
85}
86
87/// Deserialize a bencode value at the start of the buffer, return it and the remaining bytes.
88pub fn from_bytes_with_rest<'a, T>(buf: &'a [u8]) -> Result<(T, &'a [u8]), ErrorWithContext<'a>>
89where
90    T: serde::de::Deserialize<'a>,
91{
92    let mut de = BencodeDeserializer::new_from_buf(buf);
93    let v = match T::deserialize(&mut de) {
94        Ok(v) => v,
95        Err(e) => {
96            return Err(ErrorWithContext {
97                kind: e,
98                ctx: de.field_context,
99            });
100        }
101    };
102    Ok((v, de.buf))
103}
104
105#[derive(thiserror::Error, Debug)]
106pub enum Error {
107    #[error("not supported by bencode")]
108    NotSupported,
109    #[error("{0}")]
110    Custom(Box<String>), // box to reduce size
111    #[error("expected 0 or 1 for boolean, got {0}")]
112    InvalidBool(u8),
113    #[error("deserialized successfully, but {0} bytes remaining")]
114    BytesRemaining(usize),
115    #[error("invalid length: {0}")]
116    InvalidLength(usize),
117    #[error("invalid value")]
118    InvalidValue,
119    #[error("WithRawValue: invalid value")]
120    RawDeInvalidValue,
121    #[error("invalid utf-8")]
122    InvalidUtf8,
123    #[error("eof")]
124    Eof,
125}
126
127type ErrorContext<'de> = ArrayVec<ByteBuf<'de>, 4>;
128
129#[derive(Debug)]
130pub struct ErrorWithContext<'de> {
131    kind: Error,
132    ctx: ErrorContext<'de>,
133}
134
135impl ErrorWithContext<'_> {
136    pub fn kind(&self) -> &Error {
137        &self.kind
138    }
139
140    pub fn into_kind(self) -> Error {
141        self.kind
142    }
143
144    pub fn into_anyhow(self) -> anyhow::Error {
145        anyhow::Error::new(self.kind).context(format!("{:?}", self.ctx))
146    }
147}
148
149impl std::fmt::Display for ErrorWithContext<'_> {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        for (id, ctx_key) in self.ctx.iter().copied().enumerate() {
152            if id > 0 {
153                write!(f, " -> {ctx_key:?}")?;
154            } else {
155                write!(f, "{ctx_key:?}")?;
156            }
157        }
158        if !self.ctx.is_empty() {
159            write!(f, ": ")?;
160        }
161        write!(f, "{}", self.kind)
162    }
163}
164
165impl std::error::Error for ErrorWithContext<'_> {
166    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
167        Some(&self.kind)
168    }
169}
170
171impl serde::de::Error for Error {
172    fn custom<T>(msg: T) -> Self
173    where
174        T: std::fmt::Display,
175    {
176        Self::Custom(Box::new(msg.to_string()))
177    }
178}
179
180impl<'de> serde::de::Deserializer<'de> for &mut BencodeDeserializer<'de> {
181    type Error = Error;
182
183    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
184    where
185        V: serde::de::Visitor<'de>,
186    {
187        match self.buf.first().copied() {
188            Some(b'd') => self.deserialize_map(visitor),
189            Some(b'i') => self.deserialize_i64(visitor),
190            Some(b'l') => self.deserialize_seq(visitor),
191            Some(_) => self.deserialize_bytes(visitor),
192            None => Err(Error::Eof),
193        }
194    }
195
196    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
197    where
198        V: serde::de::Visitor<'de>,
199    {
200        let value = self.parse_integer::<u8>(u8::from_radix_10)?;
201        if value > 1 {
202            return Err(Error::InvalidBool(value));
203        }
204        visitor.visit_bool(value == 1)
205    }
206
207    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
208    where
209        V: serde::de::Visitor<'de>,
210    {
211        visitor.visit_i8(self.parse_integer(i8::from_radix_10_signed)?)
212    }
213
214    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
215    where
216        V: serde::de::Visitor<'de>,
217    {
218        visitor.visit_i16(self.parse_integer(i16::from_radix_10_signed)?)
219    }
220
221    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
222    where
223        V: serde::de::Visitor<'de>,
224    {
225        visitor.visit_i32(self.parse_integer(i32::from_radix_10_signed)?)
226    }
227
228    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
229    where
230        V: serde::de::Visitor<'de>,
231    {
232        visitor.visit_i64(self.parse_integer(i64::from_radix_10_signed)?)
233    }
234
235    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
236    where
237        V: serde::de::Visitor<'de>,
238    {
239        visitor.visit_u8(self.parse_integer(u8::from_radix_10)?)
240    }
241
242    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
243    where
244        V: serde::de::Visitor<'de>,
245    {
246        visitor.visit_u16(self.parse_integer(u16::from_radix_10)?)
247    }
248
249    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
250    where
251        V: serde::de::Visitor<'de>,
252    {
253        visitor.visit_u32(self.parse_integer(u32::from_radix_10)?)
254    }
255
256    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
257    where
258        V: serde::de::Visitor<'de>,
259    {
260        visitor.visit_u64(self.parse_integer(u64::from_radix_10)?)
261    }
262
263    fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
264    where
265        V: serde::de::Visitor<'de>,
266    {
267        Err(Error::NotSupported)
268    }
269
270    fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
271    where
272        V: serde::de::Visitor<'de>,
273    {
274        Err(Error::NotSupported)
275    }
276
277    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
278    where
279        V: serde::de::Visitor<'de>,
280    {
281        Err(Error::NotSupported)
282    }
283
284    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
285    where
286        V: serde::de::Visitor<'de>,
287    {
288        let b = self.parse_bytes()?;
289        let s = std::str::from_utf8(b).map_err(|_| Error::InvalidUtf8)?;
290        visitor.visit_borrowed_str(s)
291    }
292
293    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
294    where
295        V: serde::de::Visitor<'de>,
296    {
297        self.deserialize_str(visitor)
298    }
299
300    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
301    where
302        V: serde::de::Visitor<'de>,
303    {
304        let b = self.parse_bytes()?;
305        visitor.visit_borrowed_bytes(b)
306    }
307
308    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
309    where
310        V: serde::de::Visitor<'de>,
311    {
312        self.deserialize_bytes(visitor)
313    }
314
315    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
316    where
317        V: serde::de::Visitor<'de>,
318    {
319        visitor.visit_some(&mut *self)
320    }
321
322    fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
323    where
324        V: serde::de::Visitor<'de>,
325    {
326        Err(Error::NotSupported)
327    }
328
329    fn deserialize_unit_struct<V>(
330        self,
331        _name: &'static str,
332        _visitor: V,
333    ) -> Result<V::Value, Self::Error>
334    where
335        V: serde::de::Visitor<'de>,
336    {
337        Err(Error::NotSupported)
338    }
339
340    fn deserialize_newtype_struct<V>(
341        self,
342        name: &'static str,
343        visitor: V,
344    ) -> Result<V::Value, Self::Error>
345    where
346        V: serde::de::Visitor<'de>,
347    {
348        if name == TAG {
349            return visitor.visit_seq(WithRawValueDeserializer {
350                de: self,
351                buf: None,
352            });
353        }
354        Err(Error::NotSupported)
355    }
356
357    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
358    where
359        V: serde::de::Visitor<'de>,
360    {
361        self.parse_first_byte(b'l', Error::InvalidValue)?;
362        visitor.visit_seq(SeqAccess { de: self })
363    }
364
365    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
366    where
367        V: serde::de::Visitor<'de>,
368    {
369        self.deserialize_seq(visitor)
370    }
371
372    fn deserialize_tuple_struct<V>(
373        self,
374        _name: &'static str,
375        _len: usize,
376        visitor: V,
377    ) -> Result<V::Value, Self::Error>
378    where
379        V: serde::de::Visitor<'de>,
380    {
381        self.deserialize_seq(visitor)
382    }
383
384    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
385    where
386        V: serde::de::Visitor<'de>,
387    {
388        self.parse_first_byte(b'd', Error::InvalidValue)?;
389        visitor.visit_map(MapAccess { de: self })
390    }
391
392    fn deserialize_struct<V>(
393        self,
394        _name: &'static str,
395        _fields: &'static [&'static str],
396        visitor: V,
397    ) -> Result<V::Value, Self::Error>
398    where
399        V: serde::de::Visitor<'de>,
400    {
401        self.deserialize_map(visitor)
402    }
403
404    fn deserialize_enum<V>(
405        self,
406        _name: &'static str,
407        _variants: &'static [&'static str],
408        _visitor: V,
409    ) -> Result<V::Value, Self::Error>
410    where
411        V: serde::de::Visitor<'de>,
412    {
413        Err(Error::NotSupported)
414    }
415
416    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
417    where
418        V: serde::de::Visitor<'de>,
419    {
420        visitor.visit_borrowed_bytes(self.parse_bytes()?)
421    }
422
423    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
424    where
425        V: serde::de::Visitor<'de>,
426    {
427        self.deserialize_any(visitor)
428    }
429}
430
431struct MapAccess<'a, 'de> {
432    de: &'a mut BencodeDeserializer<'de>,
433}
434
435struct SeqAccess<'a, 'de> {
436    de: &'a mut BencodeDeserializer<'de>,
437}
438
439impl<'de> serde::de::MapAccess<'de> for MapAccess<'_, 'de> {
440    type Error = Error;
441
442    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
443    where
444        K: serde::de::DeserializeSeed<'de>,
445    {
446        if self.de.buf.starts_with(b"e") {
447            self.de.buf = &self.de.buf[1..];
448            return Ok(None);
449        }
450        self.de.parsing_key = true;
451        let retval = seed.deserialize(&mut *self.de)?;
452        self.de.parsing_key = false;
453        Ok(Some(retval))
454    }
455
456    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
457    where
458        V: serde::de::DeserializeSeed<'de>,
459    {
460        let value = seed.deserialize(&mut *self.de)?;
461        if self.de.field_context_did_not_fit > 0 {
462            self.de.field_context_did_not_fit -= 1;
463        } else {
464            self.de.field_context.pop();
465        }
466        Ok(value)
467    }
468}
469
470impl<'de> serde::de::SeqAccess<'de> for SeqAccess<'_, 'de> {
471    type Error = Error;
472
473    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
474    where
475        T: serde::de::DeserializeSeed<'de>,
476    {
477        if self.de.buf.starts_with(b"e") {
478            self.de.buf = &self.de.buf[1..];
479            return Ok(None);
480        }
481        Ok(Some(seed.deserialize(&mut *self.de)?))
482    }
483}
484
485struct WithRawValueDeserializer<'a, 'de> {
486    de: &'a mut BencodeDeserializer<'de>,
487    buf: Option<&'de [u8]>,
488}
489
490impl<'a, 'de> serde::de::SeqAccess<'de> for WithRawValueDeserializer<'a, 'de> {
491    type Error = Error;
492
493    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
494    where
495        T: serde::de::DeserializeSeed<'de>,
496    {
497        let buf = match self.buf {
498            None => {
499                let buf_before = self.de.buf;
500                let el = seed.deserialize(&mut *self.de)?;
501                let buf_after = self.de.buf;
502                let consumed = buf_before.len() - buf_after.len();
503                self.buf = Some(&buf_before[..consumed]);
504                return Ok(Some(el));
505            }
506            Some(buf) => buf,
507        };
508
509        struct RawValueDe<'a>(&'a [u8]);
510
511        impl<'de> serde::de::Deserializer<'de> for RawValueDe<'de> {
512            type Error = Error;
513
514            fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
515            where
516                V: serde::de::Visitor<'de>,
517            {
518                Err(Error::RawDeInvalidValue)
519            }
520
521            fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
522            where
523                V: serde::de::Visitor<'de>,
524            {
525                visitor.visit_borrowed_bytes(self.0)
526            }
527
528            fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
529            where
530                V: serde::de::Visitor<'de>,
531            {
532                visitor.visit_borrowed_bytes(self.0)
533            }
534
535            forward_to_deserialize_any! {
536                bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
537                option unit unit_struct newtype_struct seq tuple
538                tuple_struct map struct enum identifier ignored_any
539            }
540        }
541
542        let buf = seed.deserialize(RawValueDe(buf))?;
543        Ok(Some(buf))
544    }
545}
546
547#[derive(Debug, Clone, PartialEq, Eq)]
548pub struct WithRawBytes<T, Buf> {
549    pub data: T,
550    pub raw_bytes: Buf,
551}
552
553impl<T: CloneToOwned, Buf: CloneToOwned> CloneToOwned for WithRawBytes<T, Buf> {
554    type Target = WithRawBytes<T::Target, Buf::Target>;
555
556    fn clone_to_owned(&self, within_buffer: Option<&bytes::Bytes>) -> Self::Target {
557        WithRawBytes {
558            data: self.data.clone_to_owned(within_buffer),
559            raw_bytes: self.raw_bytes.clone_to_owned(within_buffer),
560        }
561    }
562}
563
564impl<T: Serialize, Buf> Serialize for WithRawBytes<T, Buf> {
565    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
566    where
567        S: serde::Serializer,
568    {
569        self.data.serialize(serializer)
570    }
571}
572
573impl<'de, T, Buf> Deserialize<'de> for WithRawBytes<T, Buf>
574where
575    T: Deserialize<'de>,
576    Buf: Deserialize<'de>,
577{
578    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
579    where
580        D: serde::Deserializer<'de>,
581    {
582        struct Visitor<T, Buf>(PhantomData<(T, Buf)>);
583        impl<'de, T, Buf> serde::de::Visitor<'de> for Visitor<T, Buf>
584        where
585            T: Deserialize<'de>,
586            Buf: Deserialize<'de>,
587        {
588            type Value = WithRawBytes<T, Buf>;
589
590            fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
591                fmt.write_str("WithRawBytes only works with librqbit_bencode")
592            }
593
594            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
595            where
596                A: serde::de::SeqAccess<'de>,
597            {
598                let data: T = match seq.next_element()? {
599                    Some(v) => v,
600                    None => {
601                        return Err(<A::Error as serde::de::Error>::custom(
602                            "expecting T as first element",
603                        ));
604                    }
605                };
606                let raw_bytes: Buf = match seq.next_element()? {
607                    Some(b) => b,
608                    None => {
609                        return Err(<A::Error as serde::de::Error>::custom(
610                            "expecting buf as second element",
611                        ));
612                    }
613                };
614                Ok(WithRawBytes { data, raw_bytes })
615            }
616        }
617        deserializer.deserialize_newtype_struct(TAG, Visitor(Default::default()))
618    }
619}
620
621#[cfg(test)]
622mod tests {
623    use buffers::ByteBuf;
624    use serde::Deserialize;
625
626    use crate::{WithRawBytes, from_bytes};
627
628    #[test]
629    fn test_deserialize_error_context() {
630        #[derive(Deserialize, Debug)]
631        struct Child {
632            #[allow(unused)]
633            key: u64,
634        }
635        #[derive(Deserialize, Debug)]
636        struct Parent {
637            #[allow(unused)]
638            child: Child,
639        }
640
641        let e = from_bytes::<Parent>(&b"d5:childd3:key2:hiee"[..]).expect_err("expected error");
642        assert_eq!(format!("{e}"), "\"child\" -> \"key\": invalid value");
643    }
644
645    #[test]
646    fn test_int() {
647        assert_eq!(from_bytes::<u8>(b"i42e").unwrap(), 42);
648        assert_eq!(from_bytes::<u16>(b"i42e").unwrap(), 42);
649        assert_eq!(from_bytes::<u32>(b"i42e").unwrap(), 42);
650        assert_eq!(from_bytes::<u64>(b"i42e").unwrap(), 42);
651
652        assert_eq!(from_bytes::<u32>(b"i4294967295e").unwrap(), 4294967295);
653
654        // negative
655        assert_eq!(from_bytes::<i8>(b"i-1e").unwrap(), -1);
656        assert_eq!(from_bytes::<i64>(b"i-1e").unwrap(), -1);
657
658        assert!(from_bytes::<u32>(b"ie").is_err());
659        assert!(from_bytes::<u32>(b"ifooe").is_err());
660        assert!(from_bytes::<u32>(b"i42").is_err());
661
662        // trailing bytes
663        assert!(from_bytes::<u32>(b"i42ee").is_err());
664    }
665
666    #[test]
667    fn test_str() {
668        assert_eq!(
669            from_bytes::<ByteBuf<'_>>(b"5:hello").unwrap(),
670            ByteBuf(b"hello")
671        );
672        assert_eq!(from_bytes::<ByteBuf<'_>>(b"0:").unwrap(), ByteBuf(b""));
673
674        assert!(from_bytes::<ByteBuf<'_>>(b"5:hell").is_err());
675        assert!(from_bytes::<ByteBuf<'_>>(b"5:helloworld").is_err());
676    }
677
678    #[test]
679    fn test_struct() {
680        #[derive(Deserialize, Eq, PartialEq, Debug)]
681        struct S<'a> {
682            key: u32,
683            #[serde(borrow)]
684            value: Option<ByteBuf<'a>>,
685        }
686
687        assert_eq!(
688            from_bytes::<S<'_>>(b"d3:keyi42ee").unwrap(),
689            S {
690                key: 42,
691                value: None
692            }
693        );
694
695        assert_eq!(
696            from_bytes::<S<'_>>(b"d3:keyi42e5:value5:helloe").unwrap(),
697            S {
698                key: 42,
699                value: Some(ByteBuf(b"hello"))
700            }
701        );
702    }
703
704    #[test]
705    fn test_list() {
706        assert_eq!(from_bytes::<Vec<ByteBuf<'_>>>(b"le").unwrap(), vec![]);
707        assert_eq!(
708            from_bytes::<Vec<ByteBuf<'_>>>(b"l5:hello2:mee").unwrap(),
709            vec![ByteBuf(b"hello"), ByteBuf(b"me")]
710        );
711    }
712
713    #[test]
714    fn test_with_raw_bytes() {
715        #[derive(Deserialize, Debug)]
716        struct TorrentInfo<'a> {
717            #[serde(borrow)]
718            name: ByteBuf<'a>,
719        }
720
721        #[derive(Deserialize, Debug)]
722        struct Torrent<'a> {
723            #[serde(borrow)]
724            info: WithRawBytes<TorrentInfo<'a>, ByteBuf<'a>>,
725        }
726
727        let t: Torrent = from_bytes(&b"d4:infod4:name5:helloee"[..]).unwrap();
728        assert_eq!(t.info.data.name, ByteBuf(b"hello"));
729        assert_eq!(t.info.raw_bytes, ByteBuf(b"d4:name5:helloe"));
730    }
731
732    #[test]
733    fn test_dict() {
734        use std::collections::BTreeMap;
735        let mut m = BTreeMap::new();
736        m.insert(ByteBuf(b"key"), ByteBuf(b"value"));
737        m.insert(ByteBuf(b"key2"), ByteBuf(b"value2"));
738        assert_eq!(
739            from_bytes::<BTreeMap<ByteBuf, ByteBuf>>(b"d3:key5:value4:key26:value2e").unwrap(),
740            m
741        );
742    }
743
744    #[test]
745    fn test_struct_unknown_field() {
746        #[derive(Deserialize, Eq, PartialEq, Debug)]
747        struct S {
748            key: u32,
749        }
750
751        assert_eq!(
752            from_bytes::<S>(b"d3:keyi42e5:value5:helloe").unwrap(),
753            S { key: 42 }
754        );
755    }
756
757    #[test]
758    fn test_complex_struct() {
759        #[derive(Deserialize, Eq, PartialEq, Debug)]
760        struct S<'a> {
761            key: u32,
762            #[serde(borrow)]
763            values: Vec<ByteBuf<'a>>,
764        }
765
766        assert_eq!(
767            from_bytes::<S>(b"d3:keyi42e6:valuesl5:hello5:worldee").unwrap(),
768            S {
769                key: 42,
770                values: vec![ByteBuf(b"hello"), ByteBuf(b"world")]
771            }
772        );
773    }
774}