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
72pub 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
87pub 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>), #[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 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 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}