1use std::{io, str};
4
5use serde::de::{self, IntoDeserializer};
6
7use crate::{
8 error::{Error, ErrorCode, Result},
9 read::{IoRead, Read, Reference, SliceRead},
10 value::ListElement,
11 ElementType,
12};
13
14#[derive(Clone, Debug, Eq, PartialEq)]
15pub(crate) enum State {
16 None,
17 Key,
18 Value,
19 SectionKey,
20 ListName,
21 ListItem(ListElement),
22}
23
24pub struct Deserializer<R> {
54 read: R,
55 level: Option<usize>,
56 state: State,
57 scratch: Vec<u8>,
58}
59
60pub fn from_reader<R, T>(reader: R) -> Result<T>
69where
70 R: io::Read,
71 T: de::DeserializeOwned,
72{
73 let mut deserializer = Deserializer::new(IoRead::new(reader));
74 let value = de::Deserialize::deserialize(&mut deserializer)?;
75 Ok(value)
76}
77
78pub fn from_slice<'a, T>(slice: &'a [u8]) -> Result<T>
85where
86 T: de::Deserialize<'a>,
87{
88 let mut deserializer = Deserializer::new(SliceRead::new(slice));
89 let value = de::Deserialize::deserialize(&mut deserializer)?;
90 Ok(value)
91}
92
93impl<'de, R> Deserializer<R>
94where
95 R: Read<'de>,
96{
97 pub fn new(read: R) -> Self {
104 let level = None;
105 let state = State::None;
106 let scratch = vec![];
107 Self {
108 read,
109 level,
110 state,
111 scratch,
112 }
113 }
114
115 #[inline]
116 fn parse_element_type(&mut self) -> Result<ElementType> {
117 self.read.parse_element_type()
118 }
119
120 #[inline]
121 fn parse_str(&mut self) -> Result<Reference<'de, '_, str>> {
122 match &self.state {
123 State::Key | State::SectionKey | State::ListName => {
124 self.scratch.clear();
125 self.read.parse_key(&mut self.scratch)
126 },
127 State::Value | State::ListItem(_) => {
128 self.scratch.clear();
129 self.read.parse_value(&mut self.scratch)
130 },
131 State::None => Err(Error::io(io::Error::from(io::ErrorKind::InvalidData), Some(self.read.position()))),
132 }
133 }
134
135 #[inline]
136 fn parse_raw_value(&mut self) -> Result<Reference<'de, '_, [u8]>> {
137 match &self.state {
138 State::Value | State::ListItem(_) => {
139 self.scratch.clear();
140 self.read.parse_value_raw(&mut self.scratch)
141 },
142 _ => Err(Error::io(io::Error::from(io::ErrorKind::InvalidData), Some(self.read.position()))),
143 }
144 }
145
146 #[inline]
147 fn peek(&mut self) -> Result<usize> {
148 match &self.state {
149 State::Key | State::SectionKey | State::ListName => self.read.peek_key(),
150 State::Value | State::ListItem(_) => self.read.peek_value(),
151 State::None => Err(Error::io(io::Error::from(io::ErrorKind::InvalidData), Some(self.read.position()))),
152 }
153 }
154}
155
156impl<R> Deserializer<IoRead<R>>
157where
158 R: io::Read,
159{
160 pub fn from_reader(reader: R) -> Self {
162 Deserializer::new(IoRead::new(reader))
163 }
164}
165
166impl<'a> Deserializer<SliceRead<'a>> {
167 pub fn from_slice(slice: &'a [u8]) -> Self {
169 Deserializer::new(SliceRead::new(slice))
170 }
171}
172
173macro_rules! deserialize_number {
174 ($method:ident => $visit:ident) => {
175 #[inline]
176 fn $method<V>(self, visitor: V) -> Result<V::Value>
177 where
178 V: de::Visitor<'de>,
179 {
180 let result = self.parse_str()?;
181 let value = result.parse().map_err::<Self::Error, _>(de::Error::custom)?;
182 visitor.$visit(value)
183 }
184 };
185}
186
187impl<'de, R> de::Deserializer<'de> for &mut Deserializer<R>
188where
189 R: Read<'de>,
190{
191 type Error = Error;
192
193 #[inline]
194 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
195 where
196 V: de::Visitor<'de>,
197 {
198 match &self.state {
199 State::Key | State::SectionKey | State::ListName => self.deserialize_str(visitor),
200 State::Value => self.deserialize_byte_buf(visitor),
201 State::ListItem(ListElement::String) => self.deserialize_seq(visitor),
202 State::ListItem(ListElement::Section) | State::None => self.deserialize_map(visitor),
203 }
204 }
205
206 #[inline]
207 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
208 where
209 V: de::Visitor<'de>,
210 {
211 let input = self.parse_str()?;
212 match &*input {
213 "yes" => visitor.visit_bool(true),
214 "no" => visitor.visit_bool(false),
215 _ => Err(Error::io(io::Error::from(io::ErrorKind::InvalidData), Some(self.read.position()))),
216 }
217 }
218
219 deserialize_number!(deserialize_i8 => visit_i8);
220 deserialize_number!(deserialize_i16 => visit_i16);
221 deserialize_number!(deserialize_i32 => visit_i32);
222 deserialize_number!(deserialize_i64 => visit_i64);
223 deserialize_number!(deserialize_u8 => visit_u8);
224 deserialize_number!(deserialize_u16 => visit_u16);
225 deserialize_number!(deserialize_u32 => visit_u32);
226 deserialize_number!(deserialize_u64 => visit_u64);
227 deserialize_number!(deserialize_f32 => visit_f32);
228 deserialize_number!(deserialize_f64 => visit_f64);
229 deserialize_number!(deserialize_char => visit_char);
230
231 #[inline]
232 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
233 where
234 V: de::Visitor<'de>,
235 {
236 match self.parse_str()? {
237 Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
238 Reference::Copied(s) => visitor.visit_str(s),
239 }
240 }
241
242 #[inline]
243 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
244 where
245 V: de::Visitor<'de>,
246 {
247 self.deserialize_str(visitor)
248 }
249
250 #[inline]
251 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
252 where
253 V: de::Visitor<'de>,
254 {
255 match self.parse_raw_value()? {
256 Reference::Borrowed(s) => visitor.visit_borrowed_bytes(s),
257 Reference::Copied(s) => visitor.visit_bytes(s),
258 }
259 }
260
261 #[inline]
262 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
263 where
264 V: de::Visitor<'de>,
265 {
266 self.deserialize_bytes(visitor)
267 }
268
269 #[inline]
270 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
271 where
272 V: de::Visitor<'de>,
273 {
274 if self.state == State::None {
275 return visitor.visit_some(self);
276 }
277
278 match self.peek()? {
279 0 => {
280 self.parse_str()?;
281 visitor.visit_none()
282 },
283 _ => visitor.visit_some(self),
284 }
285 }
286
287 #[inline]
288 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
289 where
290 V: de::Visitor<'de>,
291 {
292 visitor.visit_unit()
293 }
294
295 #[inline]
296 fn deserialize_unit_struct<V>(self, _: &'static str, visitor: V) -> Result<V::Value>
297 where
298 V: de::Visitor<'de>,
299 {
300 self.deserialize_unit(visitor)
301 }
302
303 #[inline]
304 fn deserialize_newtype_struct<V>(self, _: &'static str, visitor: V) -> Result<V::Value>
305 where
306 V: de::Visitor<'de>,
307 {
308 visitor.visit_newtype_struct(self)
309 }
310
311 #[inline]
312 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
313 where
314 V: de::Visitor<'de>,
315 {
316 visitor.visit_seq(self)
317 }
318
319 #[inline]
320 fn deserialize_tuple<V>(self, _: usize, visitor: V) -> Result<V::Value>
321 where
322 V: de::Visitor<'de>,
323 {
324 visitor.visit_seq(self)
325 }
326
327 #[inline]
328 fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, visitor: V) -> Result<V::Value>
329 where
330 V: de::Visitor<'de>,
331 {
332 visitor.visit_seq(self)
333 }
334
335 #[inline]
336 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
337 where
338 V: de::Visitor<'de>,
339 {
340 visitor.visit_map(self)
341 }
342
343 #[inline]
344 fn deserialize_struct<V>(self, _: &'static str, _: &'static [&'static str], visitor: V) -> Result<V::Value>
345 where
346 V: de::Visitor<'de>,
347 {
348 visitor.visit_map(self)
349 }
350
351 #[inline]
352 fn deserialize_enum<V>(self, _: &'static str, _: &'static [&'static str], visitor: V) -> Result<V::Value>
353 where
354 V: de::Visitor<'de>,
355 {
356 let input = self.parse_str()?;
357 visitor.visit_enum(input.into_deserializer())
358 }
359
360 #[inline]
361 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
362 where
363 V: de::Visitor<'de>,
364 {
365 self.deserialize_str(visitor)
366 }
367
368 #[inline]
369 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
370 where
371 V: de::Visitor<'de>,
372 {
373 self.deserialize_any(visitor)
374 }
375
376 #[inline]
377 fn is_human_readable(&self) -> bool {
378 false
379 }
380}
381
382#[doc(hidden)]
383impl<'de, R> de::SeqAccess<'de> for &mut Deserializer<R>
384where
385 R: Read<'de>,
386{
387 type Error = Error;
388
389 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
390 where
391 T: de::DeserializeSeed<'de>,
392 {
393 match self.parse_element_type()? {
394 ElementType::ListItem if matches!(self.state, State::ListItem(ListElement::String)) => {
395 self.state = State::Value;
396 let value = seed.deserialize(&mut **self).map(Some)?;
397
398 self.state = State::ListItem(ListElement::String);
399 Ok(value)
400 },
401 ElementType::ListEnd if matches!(self.state, State::ListItem(ListElement::String)) => {
402 self.level = self.level.map(|l| l - 1).filter(|&l| l > 0);
403 self.state = State::None;
404 Ok(None)
405 },
406 ElementType::SectionEnd if matches!(self.state, State::ListItem(ListElement::Section)) => {
407 self.level = self.level.map(|l| l - 1).filter(|&l| l > 0);
408 self.state = State::None;
409 Ok(None)
410 },
411 ElementType::SectionStart => {
412 self.level = Some(self.level.map_or(1, |l| l + 1));
413
414 self.state = State::SectionKey;
415 let _index = self.parse_str()?;
416
417 self.state = State::ListItem(ListElement::Section);
418 let value = seed.deserialize(&mut **self).map(Some)?;
419
420 self.state = State::ListItem(ListElement::Section);
421 Ok(value)
422 },
423 v => Err(Error::data(
424 ErrorCode::Message("unexpected element type".into()),
425 Some(v as u8),
426 Some(self.read.position()),
427 )),
428 }
429 }
430}
431
432#[doc(hidden)]
433impl<'de, R> de::MapAccess<'de> for &mut Deserializer<R>
434where
435 R: Read<'de>,
436{
437 type Error = Error;
438
439 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
440 where
441 K: de::DeserializeSeed<'de>,
442 {
443 match self.parse_element_type() {
444 Ok(ElementType::SectionStart) => {
445 self.level = Some(self.level.map_or(1, |l| l + 1));
446 self.state = State::SectionKey;
447 seed.deserialize(&mut **self).map(Some)
448 },
449 Ok(ElementType::ListStart) => {
450 self.level = Some(self.level.map_or(1, |l| l + 1));
451 self.state = State::ListName;
452 seed.deserialize(&mut **self).map(Some)
453 },
454 Ok(ElementType::KeyValue) => {
455 self.state = State::Key;
456 seed.deserialize(&mut **self).map(Some)
457 },
458 Ok(ElementType::SectionEnd) if self.level.is_some() => {
459 self.level = self.level.map(|l| l - 1).filter(|&l| l > 0);
460 self.state = State::None;
461 Ok(None)
462 },
463 Ok(v) => Err(Error::data(
464 ErrorCode::Message("unexpected element type".into()),
465 Some(v as u8),
466 Some(self.read.position()),
467 )),
468 Err(e) if e.is_eof() && self.level.is_none() => Ok(None),
469 Err(e) => Err(e),
470 }
471 }
472
473 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
474 where
475 V: de::DeserializeSeed<'de>,
476 {
477 match &self.state {
478 State::ListName => {
479 self.state = State::ListItem(ListElement::String);
480 seed.deserialize(&mut **self)
481 },
482 State::Key => {
483 self.state = State::Value;
484 seed.deserialize(&mut **self)
485 },
486 _ => {
487 self.state = State::None;
488 seed.deserialize(&mut **self)
489 },
490 }
491 }
492}
493
494#[cfg(test)]
495mod tests {
496 use indexmap::{indexmap, IndexMap};
497 use pretty_assertions::assert_eq;
498 use serde_derive::Deserialize;
499
500 use super::*;
501
502 #[test]
503 fn deserialize_reader_example() {
504 #[derive(Debug, Deserialize, Eq, PartialEq)]
505 struct RootSection {
506 key1: String,
507 section1: MainSection,
508 }
509
510 #[derive(Debug, Deserialize, Eq, PartialEq)]
511 struct MainSection {
512 #[serde(rename = "sub-section")]
513 sub_section: Option<SubSection>,
514 list1: Vec<String>,
515 }
516
517 #[derive(Debug, Deserialize, Eq, PartialEq)]
518 struct SubSection {
519 key2: String,
520 }
521
522 #[rustfmt::skip]
523 let data: &[_] = &[
524 3, 4, b'k', b'e', b'y', b'1', 0, 6, b'v', b'a', b'l', b'u', b'e', b'1',
526 1, 8, b's', b'e', b'c', b't', b'i', b'o', b'n', b'1',
528 1, 11, b's', b'u', b'b', b'-', b's', b'e', b'c', b't', b'i', b'o', b'n',
530 3, 4, b'k', b'e', b'y', b'2', 0, 6, b'v', b'a', b'l', b'u', b'e', b'2',
532 2,
534 4, 5, b'l', b'i', b's', b't', b'1',
536 5, 0, 5, b'i', b't', b'e', b'm', b'1',
538 5, 0, 5, b'i', b't', b'e', b'm', b'2',
540 6,
542 2,
544 ];
545
546 let actual: RootSection = from_reader(data).unwrap();
547 assert_eq!(
548 actual,
549 RootSection {
550 key1: "value1".to_string(),
551 section1: MainSection {
552 sub_section: Some(SubSection {
553 key2: "value2".to_string(),
554 }),
555 list1: vec!["item1".to_string(), "item2".to_string()],
556 },
557 }
558 );
559 }
560
561 #[test]
562 fn deserialize_reader_none() {
563 #[derive(Debug, Deserialize, Eq, PartialEq)]
564 struct RootSection {
565 key1: String,
566 section1: MainSection,
567 }
568
569 #[derive(Debug, Deserialize, Eq, PartialEq)]
570 struct MainSection {
571 #[serde(rename = "sub-section")]
572 sub_section: Option<SubSection>,
573 list1: Vec<String>,
574 }
575
576 #[derive(Debug, Deserialize, Eq, PartialEq)]
577 struct SubSection {
578 key2: String,
579 }
580
581 #[rustfmt::skip]
582 let data: &[_] = &[
583 3, 4, b'k', b'e', b'y', b'1', 0, 6, b'v', b'a', b'l', b'u', b'e', b'1',
585 1, 8, b's', b'e', b'c', b't', b'i', b'o', b'n', b'1',
587 4, 5, b'l', b'i', b's', b't', b'1',
589 5, 0, 5, b'i', b't', b'e', b'm', b'1',
591 5, 0, 5, b'i', b't', b'e', b'm', b'2',
593 6,
595 2,
597 ];
598
599 let actual: RootSection = from_reader(data).unwrap();
600 assert_eq!(
601 actual,
602 RootSection {
603 key1: "value1".to_string(),
604 section1: MainSection {
605 sub_section: None,
606 list1: vec!["item1".to_string(), "item2".to_string()],
607 },
608 }
609 );
610 }
611
612 #[test]
613 fn deserialize_reader_pools() {
614 #[derive(Debug, Deserialize, Eq, PartialEq)]
615 struct Pool {
616 base: String,
617 size: u32,
618 online: u32,
619 offline: u32,
620 leases: Vec<Lease>,
621 }
622
623 #[derive(Debug, Deserialize, Eq, PartialEq)]
624 struct Lease {
625 address: String,
626 identity: Option<String>,
627 status: Status,
628 }
629
630 #[derive(Debug, Deserialize, Eq, PartialEq)]
631 enum Status {
632 #[serde(rename = "online")]
633 Online,
634 #[serde(rename = "offline")]
635 Offline,
636 }
637
638 #[rustfmt::skip]
639 let data: &[_] = &[
640 1, 7, b'p', b'o', b'o', b'l', b'-', b'0', b'1',
642 3, 4, b'b', b'a', b's', b'e', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'1',
644 3, 4, b's', b'i', b'z', b'e', 0, 1, b'4',
646 3, 6, b'o', b'n', b'l', b'i', b'n', b'e', 0, 1, b'3',
648 3, 7, b'o', b'f', b'f', b'l', b'i', b'n', b'e', 0, 1, b'1',
650 1, 6, b'l', b'e', b'a', b's', b'e', b's',
652 1, 1, b'0',
654 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'2',
656 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 11, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', b'-', b'0', b'1',
658 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 6, b'o', b'n', b'l', b'i', b'n', b'e',
660 2,
662 1, 1, b'1',
664 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'3',
666 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 11, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', b'-', b'0', b'2',
668 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 6, b'o', b'n', b'l', b'i', b'n', b'e',
670 2,
672 1, 1, b'2',
674 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'4',
676 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 11, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', b'-', b'0', b'3',
678 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 6, b'o', b'n', b'l', b'i', b'n', b'e',
680 2,
682 1, 1, b'3',
684 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'5',
686 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 0,
688 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 7, b'o', b'f', b'f', b'l', b'i', b'n', b'e',
690 2,
692 2,
694 2,
696 ];
697
698 let actual: IndexMap<String, Pool> = from_reader(data).unwrap();
699 assert_eq!(
700 actual,
701 indexmap! {
702 "pool-01".to_string() => Pool {
703 base: "192.0.2.1".to_string(),
704 size: 4,
705 online: 3,
706 offline: 1,
707 leases: vec![
708 Lease {
709 address: "192.0.2.2".to_string(),
710 identity: Some("identity-01".to_string()),
711 status: Status::Online,
712 },
713 Lease {
714 address: "192.0.2.3".to_string(),
715 identity: Some("identity-02".to_string()),
716 status: Status::Online,
717 },
718 Lease {
719 address: "192.0.2.4".to_string(),
720 identity: Some("identity-03".to_string()),
721 status: Status::Online,
722 },
723 Lease {
724 address: "192.0.2.5".to_string(),
725 identity: None,
726 status: Status::Offline,
727 },
728 ],
729 },
730 }
731 );
732 }
733
734 #[test]
735 fn deserialize_reader_certs() {
736 #[derive(Debug, Deserialize, Eq, PartialEq)]
737 enum Type {
738 X509,
739 #[serde(rename = "X509_AC")]
740 X509Ac,
741 #[serde(rename = "X509_CRL")]
742 X509Crl,
743 #[serde(rename = "OCSP_RESPONSE")]
744 OcspResponse,
745 #[serde(rename = "PUBKEY")]
746 Pubkey,
747 }
748
749 #[derive(Debug, Deserialize, Eq, PartialEq)]
750 enum Flag {
751 #[serde(rename = "NONE")]
752 None,
753 CA,
754 AA,
755 #[serde(rename = "OCSP")]
756 Ocsp,
757 }
758
759 #[derive(Debug, Deserialize, Eq, PartialEq)]
760 struct CertResponse {
761 r#type: Type,
762 flag: Flag,
763 #[serde(with = "serde_bytes")]
764 data: Vec<u8>,
765 }
766
767 #[rustfmt::skip]
768 let data: &[_] = &[
769 3, 4, b't', b'y', b'p', b'e', 0, 4, b'X', b'5', b'0', b'9',
771 3, 4, b'f', b'l', b'a', b'g', 0, 2, b'C', b'A',
773 3, 4, b'd', b'a', b't', b'a', 0, 4, 0x00, 0x01, 0x02, 0x03,
775 ];
776
777 let actual: CertResponse = from_reader(data).unwrap();
778 assert_eq!(
779 actual,
780 CertResponse {
781 r#type: Type::X509,
782 flag: Flag::CA,
783 data: vec![0x00, 0x01, 0x02, 0x03],
784 }
785 );
786 }
787
788 #[test]
789 fn deserialize_slice_example() {
790 #[derive(Debug, Deserialize, Eq, PartialEq)]
791 struct RootSection<'a> {
792 key1: &'a str,
793 section1: MainSection<'a>,
794 }
795
796 #[derive(Debug, Deserialize, Eq, PartialEq)]
797 struct MainSection<'a> {
798 #[serde(borrow, rename = "sub-section")]
799 sub_section: Option<SubSection<'a>>,
800 list1: Vec<&'a str>,
801 }
802
803 #[derive(Debug, Deserialize, Eq, PartialEq)]
804 struct SubSection<'a> {
805 key2: &'a str,
806 }
807
808 #[rustfmt::skip]
809 let data = &[
810 3, 4, b'k', b'e', b'y', b'1', 0, 6, b'v', b'a', b'l', b'u', b'e', b'1',
812 1, 8, b's', b'e', b'c', b't', b'i', b'o', b'n', b'1',
814 1, 11, b's', b'u', b'b', b'-', b's', b'e', b'c', b't', b'i', b'o', b'n',
816 3, 4, b'k', b'e', b'y', b'2', 0, 6, b'v', b'a', b'l', b'u', b'e', b'2',
818 2,
820 4, 5, b'l', b'i', b's', b't', b'1',
822 5, 0, 5, b'i', b't', b'e', b'm', b'1',
824 5, 0, 5, b'i', b't', b'e', b'm', b'2',
826 6,
828 2,
830 ];
831
832 let actual: RootSection = from_slice(data).unwrap();
833 assert_eq!(
834 actual,
835 RootSection {
836 key1: "value1",
837 section1: MainSection {
838 sub_section: Some(SubSection { key2: "value2" }),
839 list1: vec!["item1", "item2",],
840 },
841 }
842 );
843 }
844
845 #[test]
846 fn deserialize_slice_none() {
847 #[derive(Debug, Deserialize, Eq, PartialEq)]
848 struct RootSection<'a> {
849 key1: &'a str,
850 section1: MainSection<'a>,
851 }
852
853 #[derive(Debug, Deserialize, Eq, PartialEq)]
854 struct MainSection<'a> {
855 #[serde(borrow, rename = "sub-section")]
856 sub_section: Option<SubSection<'a>>,
857 list1: Vec<&'a str>,
858 }
859
860 #[derive(Debug, Deserialize, Eq, PartialEq)]
861 struct SubSection<'a> {
862 key2: &'a str,
863 }
864
865 #[rustfmt::skip]
866 let data = &[
867 3, 4, b'k', b'e', b'y', b'1', 0, 6, b'v', b'a', b'l', b'u', b'e', b'1',
869 1, 8, b's', b'e', b'c', b't', b'i', b'o', b'n', b'1',
871 4, 5, b'l', b'i', b's', b't', b'1',
873 5, 0, 5, b'i', b't', b'e', b'm', b'1',
875 5, 0, 5, b'i', b't', b'e', b'm', b'2',
877 6,
879 2,
881 ];
882
883 let actual: RootSection = from_slice(data).unwrap();
884 assert_eq!(
885 actual,
886 RootSection {
887 key1: "value1",
888 section1: MainSection {
889 sub_section: None,
890 list1: vec!["item1", "item2",],
891 },
892 }
893 );
894 }
895
896 #[test]
897 fn deserialize_slice_pools() {
898 #[derive(Debug, Deserialize, Eq, PartialEq)]
899 struct Pool<'a> {
900 base: &'a str,
901 size: u32,
902 online: u32,
903 offline: u32,
904 #[serde(borrow)]
905 leases: Vec<Lease<'a>>,
906 }
907
908 #[derive(Debug, Deserialize, Eq, PartialEq)]
909 struct Lease<'a> {
910 address: &'a str,
911 identity: Option<&'a str>,
912 status: Status,
913 }
914
915 #[derive(Debug, Deserialize, Eq, PartialEq)]
916 enum Status {
917 #[serde(rename = "online")]
918 Online,
919 #[serde(rename = "offline")]
920 Offline,
921 }
922
923 #[rustfmt::skip]
924 let data = &[
925 1, 7, b'p', b'o', b'o', b'l', b'-', b'0', b'1',
927 3, 4, b'b', b'a', b's', b'e', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'1',
929 3, 4, b's', b'i', b'z', b'e', 0, 1, b'4',
931 3, 6, b'o', b'n', b'l', b'i', b'n', b'e', 0, 1, b'3',
933 3, 7, b'o', b'f', b'f', b'l', b'i', b'n', b'e', 0, 1, b'1',
935 1, 6, b'l', b'e', b'a', b's', b'e', b's',
937 1, 1, b'0',
939 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'2',
941 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 11, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', b'-', b'0', b'1',
943 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 6, b'o', b'n', b'l', b'i', b'n', b'e',
945 2,
947 1, 1, b'1',
949 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'3',
951 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 11, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', b'-', b'0', b'2',
953 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 6, b'o', b'n', b'l', b'i', b'n', b'e',
955 2,
957 1, 1, b'2',
959 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'4',
961 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 11, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', b'-', b'0', b'3',
963 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 6, b'o', b'n', b'l', b'i', b'n', b'e',
965 2,
967 1, 1, b'3',
969 3, 7, b'a', b'd', b'd', b'r', b'e', b's', b's', 0, 9, b'1', b'9', b'2', b'.', b'0', b'.', b'2', b'.', b'5',
971 3, 8, b'i', b'd', b'e', b'n', b't', b'i', b't', b'y', 0, 0,
973 3, 6, b's', b't', b'a', b't', b'u', b's', 0, 7, b'o', b'f', b'f', b'l', b'i', b'n', b'e',
975 2,
977 2,
979 2,
981 ];
982
983 let actual: IndexMap<&str, Pool> = from_slice(data).unwrap();
984 assert_eq!(
985 actual,
986 indexmap! {
987 "pool-01" => Pool {
988 base: "192.0.2.1",
989 size: 4,
990 online: 3,
991 offline: 1,
992 leases: vec![
993 Lease {
994 address: "192.0.2.2",
995 identity: Some("identity-01"),
996 status: Status::Online,
997 },
998 Lease {
999 address: "192.0.2.3",
1000 identity: Some("identity-02"),
1001 status: Status::Online,
1002 },
1003 Lease {
1004 address: "192.0.2.4",
1005 identity: Some("identity-03"),
1006 status: Status::Online,
1007 },
1008 Lease {
1009 address: "192.0.2.5",
1010 identity: None,
1011 status: Status::Offline,
1012 },
1013 ],
1014 },
1015 }
1016 );
1017 }
1018
1019 #[test]
1020 fn deserialize_slice_certs() {
1021 #[derive(Debug, Deserialize, Eq, PartialEq)]
1022 enum Type {
1023 X509,
1024 #[serde(rename = "X509_AC")]
1025 X509Ac,
1026 #[serde(rename = "X509_CRL")]
1027 X509Crl,
1028 #[serde(rename = "OCSP_RESPONSE")]
1029 OcspResponse,
1030 #[serde(rename = "PUBKEY")]
1031 Pubkey,
1032 }
1033
1034 #[derive(Debug, Deserialize, Eq, PartialEq)]
1035 enum Flag {
1036 #[serde(rename = "NONE")]
1037 None,
1038 CA,
1039 AA,
1040 #[serde(rename = "OCSP")]
1041 Ocsp,
1042 }
1043
1044 #[derive(Debug, Deserialize, Eq, PartialEq)]
1045 struct CertResponse {
1046 r#type: Type,
1047 flag: Flag,
1048 #[serde(with = "serde_bytes")]
1049 data: Vec<u8>,
1050 }
1051
1052 #[rustfmt::skip]
1053 let data = &[
1054 3, 4, b't', b'y', b'p', b'e', 0, 4, b'X', b'5', b'0', b'9',
1056 3, 4, b'f', b'l', b'a', b'g', 0, 2, b'C', b'A',
1058 3, 4, b'd', b'a', b't', b'a', 0, 4, 0x00, 0x01, 0x02, 0x03,
1060 ];
1061
1062 let actual: CertResponse = from_slice(data).unwrap();
1063 assert_eq!(
1064 actual,
1065 CertResponse {
1066 r#type: Type::X509,
1067 flag: Flag::CA,
1068 data: vec![0x00, 0x01, 0x02, 0x03],
1069 }
1070 );
1071 }
1072}