1use std::borrow::Cow;
4use std::rc::Rc;
5use std::{fmt, mem};
6
7use log::{debug, trace};
8use serde::de::{self, IntoDeserializer, Unexpected};
9use serde::Deserializer;
10
11use crate::de::buffer::CowBuffer;
12use crate::{SgmlEvent, SgmlFragment};
13
14mod buffer;
15
16pub fn from_fragment<'de, T>(fragment: SgmlFragment<'de>) -> Result<T, DeserializationError>
70where
71 T: de::Deserialize<'de>,
72{
73 let mut reader = SgmlDeserializer::from_fragment(fragment)?;
74 T::deserialize(&mut reader)
75}
76
77#[derive(Debug)]
79pub struct SgmlDeserializer<'de> {
80 events: std::vec::IntoIter<SgmlEvent<'de>>,
81 stack: Vec<Cow<'de, str>>,
82 map_key: Option<Rc<str>>,
83 accumulated_text: Option<Cow<'de, str>>,
84}
85
86#[derive(Debug, thiserror::Error)]
88pub enum DeserializationError {
89 #[error("unexpected end of content")]
90 UnexpectedEof,
91 #[error("empty stack")]
92 EmptyStack,
93 #[error("expected start tag")]
94 ExpectedStartTag,
95 #[error("mismatched close tag: expected </{expected}>, found </{found}>")]
96 MismatchedCloseTag { expected: String, found: String },
97 #[error("deserialization of '{0}' is not supported")]
99 Unsupported(SgmlEvent<'static>),
100
101 #[error("error parsing integer value: {source}")]
102 ParseIntError {
103 #[from]
104 source: std::num::ParseIntError,
105 },
106 #[error("error parsing float value: {source}")]
107 ParseFloatError {
108 #[from]
109 source: std::num::ParseFloatError,
110 },
111
112 #[error("{0}")]
113 Message(String),
114}
115
116impl<'de> SgmlDeserializer<'de> {
117 pub fn from_fragment(fragment: SgmlFragment<'de>) -> Result<Self, DeserializationError> {
118 let mut reader = SgmlDeserializer {
119 events: fragment.into_vec().into_iter(),
120 stack: Vec::new(),
121 map_key: None,
122 accumulated_text: None,
123 };
124 reader.normalize_at_cursor()?;
125 Ok(reader)
126 }
127
128 fn advance(&mut self) -> Result<SgmlEvent<'de>, DeserializationError> {
129 if let Some(next) = self.events.next() {
130 self.normalize_at_cursor()?;
131 Ok(next)
132 } else {
133 Err(DeserializationError::UnexpectedEof)
134 }
135 }
136
137 fn peek(&self) -> Result<&SgmlEvent<'de>, DeserializationError> {
138 let current = self
139 .events
140 .as_slice()
141 .get(0)
142 .ok_or(DeserializationError::UnexpectedEof)?;
143 trace!("peeked: {:?}", current);
144 Ok(current)
145 }
146
147 fn peek_mut(&mut self) -> Result<&mut SgmlEvent<'de>, DeserializationError> {
148 let current = self
149 .events
150 .as_mut_slice()
151 .get_mut(0)
152 .ok_or(DeserializationError::UnexpectedEof)?;
153 trace!("peeked: {:?}", current);
154 Ok(current)
155 }
156
157 fn peek_content_type(&self) -> Result<PeekContentType, DeserializationError> {
158 let mut contains_text = false;
159 let contains_child_elements = self
160 .events
161 .as_slice()
162 .iter()
163 .skip(1)
164 .find_map(|event| match event {
165 SgmlEvent::OpenStartTag { .. } => Some(true),
166 SgmlEvent::EndTag { .. } => Some(false),
167 SgmlEvent::Character(text) if !text.is_empty() => {
168 contains_text = true;
169 None
170 }
171 _ => None,
172 })
173 .ok_or(DeserializationError::UnexpectedEof)?;
174
175 let content = PeekContentType {
176 contains_child_elements,
177 contains_text,
178 };
179 trace!("peeked content type: {:?}", content);
180 Ok(content)
181 }
182
183 fn normalize_at_cursor(&mut self) -> Result<(), DeserializationError> {
186 let event = match self.events.as_mut_slice().get_mut(0) {
187 Some(event) => event,
188 None => return Ok(()),
189 };
190 match event {
191 SgmlEvent::MarkupDeclaration { .. }
192 | SgmlEvent::ProcessingInstruction(_)
193 | SgmlEvent::MarkedSection { .. } => {}
194 SgmlEvent::OpenStartTag { name } | SgmlEvent::EndTag { name } if name.is_empty() => {}
195 _ => return Ok(()),
196 }
197 Err(DeserializationError::Unsupported(
198 self.events.next().unwrap().into_owned(),
199 ))
200 }
201
202 fn expect_start_tag(&self) -> Result<&Cow<'de, str>, DeserializationError> {
203 match self.peek() {
204 Ok(SgmlEvent::OpenStartTag { name }) => Ok(name),
205 _ => Err(DeserializationError::ExpectedStartTag),
206 }
207 }
208
209 fn push_elt(&mut self) -> Result<&str, DeserializationError> {
211 let stag = match self.events.next() {
212 Some(SgmlEvent::OpenStartTag { name }) => name,
213 _ => return Err(DeserializationError::ExpectedStartTag),
214 };
215 debug!("push({}): {:?}", self.stack.len(), stag);
216 self.stack.push(stag);
217 self.normalize_at_cursor()?;
218 Ok(self.stack.last().unwrap())
219 }
220
221 fn pop_elt(&mut self) -> Result<(), DeserializationError> {
223 let stack_size = self.stack.len();
224 trace!(
225 "popping({}): {:?}",
226 stack_size - 1,
227 &self.stack[stack_size - 1]
228 );
229 loop {
230 match self
231 .events
232 .next()
233 .ok_or(DeserializationError::UnexpectedEof)?
234 {
235 SgmlEvent::XmlCloseEmptyElement => {
236 self.stack.pop();
237 return Ok(());
238 }
239 SgmlEvent::EndTag { name } => {
240 self.check_stack_size(stack_size);
241 let expected = self.stack.pop().unwrap();
242 if name != expected {
243 return Err(DeserializationError::MismatchedCloseTag {
244 expected: expected.to_string(),
245 found: name.to_string(),
246 });
247 }
248 debug!("popped({}): {:?}", stack_size, name);
249 return Ok(());
250 }
251 SgmlEvent::OpenStartTag { name } => {
252 self.stack.push(name);
253 self.pop_elt()?;
254 }
255 _ => {}
256 };
257 }
258 }
259
260 fn advance_to_content(&mut self) -> Result<(), DeserializationError> {
264 while let SgmlEvent::Attribute { .. } | SgmlEvent::CloseStartTag = self.peek()? {
265 self.advance()?;
266 }
267 Ok(())
268 }
269
270 fn consume_text<'r, V: de::Visitor<'r>>(
274 &mut self,
275 ) -> Result<Cow<'de, str>, DeserializationError> {
276 if let Some(accumulated_text) = self.accumulated_text.take() {
277 debug!("consume_text accumulated");
278 return Ok(accumulated_text);
279 }
280
281 debug!("consume_text");
282 if let SgmlEvent::Attribute { name, value } = self.peek_mut()? {
283 let value = mem::take(value);
284 debug!("consumed text from attribute({}): {:?}", name, value);
285 self.advance()?;
286 return Ok(value.unwrap_or_default());
287 }
288
289 let starting_stack_size = self.stack.len();
290 self.push_elt()?;
291
292 let mut text = CowBuffer::new();
293
294 loop {
295 match self.peek_mut()? {
296 SgmlEvent::OpenStartTag { .. } => {
297 self.push_elt()?;
298 }
299 SgmlEvent::EndTag { .. } => {
300 self.pop_elt()?;
301 if self.stack.len() == starting_stack_size {
302 break;
303 }
304 }
305 SgmlEvent::Character(t) => {
306 text.push_cow(mem::take(t));
307 self.advance()?;
308 }
309 _ => {
310 self.advance()?;
311 }
312 }
313 }
314
315 debug!("consumed text content: {:?}", text.as_str());
316 Ok(text.into_cow())
317 }
318
319 fn do_map<'r, V>(
320 &'r mut self,
321 visitor: V,
322 emit_value: bool,
323 ) -> Result<V::Value, DeserializationError>
324 where
325 V: de::Visitor<'de>,
326 {
327 self.push_elt()?;
328 let stack_size = self.stack.len();
329 let value = visitor.visit_map(MapAccess::new(self, emit_value))?;
330 self.check_stack_size(stack_size);
331 self.pop_elt()?;
332
333 Ok(value)
334 }
335
336 #[track_caller]
337 fn check_stack_size(&self, expected_size: usize) {
338 let stack = &self.stack;
339
340 debug_assert_eq!(
341 expected_size,
342 stack.len(),
343 "unstable stack: {action} {delta:?}",
344 action = if stack.len() > expected_size {
345 "added"
346 } else {
347 "removed"
348 },
349 delta = stack.iter().skip(expected_size).collect::<Vec<_>>(),
350 );
351 }
352}
353
354macro_rules! forward_parse {
355 ($deserialize:ident => $visit:ident) => {
356 fn $deserialize<V>(self, visitor: V) -> Result<V::Value, DeserializationError>
357 where
358 V: de::Visitor<'de>,
359 {
360 trace!(stringify!($deserialize));
361 let value = self.consume_text::<V>()?.parse()?;
362 visitor.$visit(value)
363 }
364 };
365}
366
367impl<'de, 'r> Deserializer<'de> for &'r mut SgmlDeserializer<'de> {
368 type Error = DeserializationError;
369
370 forward_parse!(deserialize_i8 => visit_i8);
371 forward_parse!(deserialize_i16 => visit_i16);
372 forward_parse!(deserialize_i32 => visit_i32);
373 forward_parse!(deserialize_i64 => visit_i64);
374 forward_parse!(deserialize_u8 => visit_u8);
375 forward_parse!(deserialize_u16 => visit_u16);
376 forward_parse!(deserialize_u32 => visit_u32);
377 forward_parse!(deserialize_u64 => visit_u64);
378 forward_parse!(deserialize_f32 => visit_f32);
379 forward_parse!(deserialize_f64 => visit_f64);
380
381 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
382 where
383 V: de::Visitor<'de>,
384 {
385 trace!("deserialize_bool");
386
387 if let SgmlEvent::Attribute { name, value } = self.peek()? {
388 let value = value.as_deref().unwrap_or_default();
390 if value.is_empty() || value.eq_ignore_ascii_case(name) {
391 self.advance()?;
392 return visitor.visit_bool(true);
393 }
394 }
395
396 let str = self.consume_text::<V>()?;
397 if str == "1" || str.eq_ignore_ascii_case("true") {
398 visitor.visit_bool(true)
399 } else if str == "0" || str.eq_ignore_ascii_case("false") {
400 visitor.visit_bool(false)
401 } else {
402 Err(de::Error::invalid_value(
403 Unexpected::Str(&str),
404 &"a boolean",
405 ))
406 }
407 }
408
409 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
410 where
411 V: de::Visitor<'de>,
412 {
413 trace!("deserialize_str");
414 match self.consume_text::<V>()? {
415 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
416 Cow::Owned(s) => visitor.visit_string(s),
417 }
418 }
419
420 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
421 where
422 V: de::Visitor<'de>,
423 {
424 trace!("deserialize_string -> str");
425 self.deserialize_str(visitor)
426 }
427
428 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
429 where
430 V: de::Visitor<'de>,
431 {
432 trace!("deserialize_char -> str");
433 self.deserialize_str(visitor)
434 }
435
436 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
437 where
438 V: de::Visitor<'de>,
439 {
440 trace!("deserialize_bytes -> str");
441 self.deserialize_str(visitor)
442 }
443
444 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
445 where
446 V: de::Visitor<'de>,
447 {
448 trace!("deserialize_byte_buf -> str");
449 self.deserialize_str(visitor)
450 }
451
452 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
453 where
454 V: de::Visitor<'de>,
455 {
456 trace!("deserialize_identifier -> str");
457 self.deserialize_str(visitor)
458 }
459
460 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
461 where
462 V: de::Visitor<'de>,
463 {
464 visitor.visit_some(self)
465 }
466
467 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
468 where
469 V: de::Visitor<'de>,
470 {
471 if self.accumulated_text.take().is_some() {
472 trace!("deserialize_unit -> accumulated text");
473 return visitor.visit_unit();
474 }
475
476 trace!("deserialize_unit");
477 match self.peek()? {
478 SgmlEvent::OpenStartTag { .. } => {
479 self.push_elt()?;
480 self.pop_elt()?;
481 visitor.visit_unit()
482 }
483 SgmlEvent::Attribute { .. } => {
484 self.advance()?;
485 visitor.visit_unit()
486 }
487 _ => self.deserialize_any(visitor),
488 }
489 }
490
491 fn deserialize_unit_struct<V>(
492 self,
493 name: &'static str,
494 visitor: V,
495 ) -> Result<V::Value, Self::Error>
496 where
497 V: de::Visitor<'de>,
498 {
499 trace!("deserialize_unit_struct ({}) -> unit", name);
500 self.deserialize_unit(visitor)
501 }
502
503 fn deserialize_newtype_struct<V>(
504 self,
505 name: &'static str,
506 visitor: V,
507 ) -> Result<V::Value, Self::Error>
508 where
509 V: de::Visitor<'de>,
510 {
511 trace!("deserialize_newtype_struct ({})", name);
512 visitor.visit_newtype_struct(self)
513 }
514
515 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
516 where
517 V: de::Visitor<'de>,
518 {
519 trace!("deserialize_seq (tag: {:?})", self.map_key);
520 let stack_size = self.stack.len();
521
522 let tag_name = self.map_key.take().map(Into::into);
523 let value = visitor.visit_seq(SeqAccess::new(self, tag_name))?;
524
525 self.check_stack_size(stack_size);
526
527 Ok(value)
528 }
529
530 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
531 where
532 V: de::Visitor<'de>,
533 {
534 trace!("deserialize_tuple ({} items) -> seq", len);
535 self.deserialize_seq(visitor)
536 }
537
538 fn deserialize_tuple_struct<V>(
539 self,
540 name: &'static str,
541 len: usize,
542 visitor: V,
543 ) -> Result<V::Value, Self::Error>
544 where
545 V: de::Visitor<'de>,
546 {
547 trace!("deserialize_tuple_struct({}, {} items) -> seq", name, len);
548 self.deserialize_seq(visitor)
549 }
550
551 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
552 where
553 V: de::Visitor<'de>,
554 {
555 trace!("deserialize_map");
556 self.do_map(visitor, false)
557 }
558
559 fn deserialize_struct<V>(
560 self,
561 name: &'static str,
562 fields: &'static [&'static str],
563 visitor: V,
564 ) -> Result<V::Value, Self::Error>
565 where
566 V: de::Visitor<'de>,
567 {
568 trace!("deserialize_struct({}) -> map", name);
569 self.do_map(visitor, fields.contains(&"$value"))
570 }
571
572 fn deserialize_enum<V>(
573 self,
574 name: &'static str,
575 _variants: &'static [&'static str],
576 visitor: V,
577 ) -> Result<V::Value, Self::Error>
578 where
579 V: de::Visitor<'de>,
580 {
581 trace!("deserialize_enum({})", name);
582
583 let stack_size = self.stack.len();
584
585 let enum_within_element = self
588 .map_key
589 .as_deref()
590 .and_then(|map_key| {
591 self.expect_start_tag()
592 .ok()
593 .map(|start_tag| start_tag == map_key)
594 })
595 .unwrap_or(false);
596
597 let use_tag_name_for_variant = if enum_within_element {
600 if self.peek_content_type()?.contains_child_elements {
601 trace!("enum within element; using content elt");
602 self.push_elt()?;
605 self.advance_to_content()?;
606 true
607 } else {
608 trace!("enum within element; using text content");
609 false
612 }
613 } else {
614 true
617 };
618
619 let value = visitor.visit_enum(EnumAccess::new(self, use_tag_name_for_variant))?;
620 if enum_within_element && use_tag_name_for_variant {
621 self.pop_elt()?;
622 }
623
624 self.check_stack_size(stack_size);
625 Ok(value)
626 }
627
628 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
629 where
630 V: de::Visitor<'de>,
631 {
632 trace!("deserialize_any");
633
634 if self.accumulated_text.is_some() {
635 return self.deserialize_str(visitor);
636 }
637 match self.peek()? {
638 SgmlEvent::OpenStartTag { .. } => {
639 let content = self.peek_content_type()?;
640 if content.contains_child_elements {
641 self.deserialize_map(visitor)
642 } else if content.contains_text {
643 self.deserialize_str(visitor)
644 } else {
645 self.deserialize_unit(visitor)
646 }
647 }
648 SgmlEvent::Attribute { .. } => self.deserialize_str(visitor),
649 _ => Err(DeserializationError::ExpectedStartTag),
650 }
651 }
652
653 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
654 where
655 V: de::Visitor<'de>,
656 {
657 trace!("deserialize_ignored_any -> unit");
658 self.deserialize_unit(visitor)
659 }
660}
661
662impl de::Error for DeserializationError {
663 fn custom<T: fmt::Display>(msg: T) -> Self {
664 DeserializationError::Message(msg.to_string())
665 }
666}
667
668struct MapAccess<'de, 'r> {
669 de: &'r mut SgmlDeserializer<'de>,
670 stack_size: usize,
671 map_key: Option<Rc<str>>,
672 content_strategy: ContentStrategy,
673 text_content: Option<CowBuffer<'de>>,
674 next_entry_is_dollarvalue: bool,
675}
676
677impl<'de, 'r> MapAccess<'de, 'r> {
678 fn new(de: &'r mut SgmlDeserializer<'de>, emit_value: bool) -> Self {
679 let stack_size = de.stack.len();
680 let content_strategy = if emit_value {
681 if de
682 .peek_content_type()
683 .map(|content| content.contains_child_elements)
684 .unwrap_or(false)
685 {
686 ContentStrategy::ElementsAreDollarValue
687 } else {
688 ContentStrategy::TextOnly
689 }
690 } else {
691 ContentStrategy::ElementsAreMapEntries
692 };
693 Self {
694 de,
695 stack_size,
696 map_key: None,
697 content_strategy,
698 text_content: (content_strategy == ContentStrategy::TextOnly).then(CowBuffer::new),
699 next_entry_is_dollarvalue: false,
700 }
701 }
702}
703
704#[derive(Clone, Copy, PartialEq)]
705enum ContentStrategy {
706 TextOnly,
708 ElementsAreMapEntries,
710 ElementsAreDollarValue,
712}
713
714impl<'de, 'r> de::MapAccess<'de> for MapAccess<'de, 'r> {
715 type Error = DeserializationError;
716
717 fn next_key_seed<K: de::DeserializeSeed<'de>>(
718 &mut self,
719 seed: K,
720 ) -> Result<Option<K::Value>, Self::Error> {
721 trace!("next_key_seed");
722 self.de.check_stack_size(self.stack_size);
723
724 loop {
725 break match self.de.peek_mut()? {
726 SgmlEvent::EndTag { .. } | SgmlEvent::XmlCloseEmptyElement => {
727 if self.text_content.is_some() {
728 self.next_entry_is_dollarvalue = true;
729 debug!("next key: $value");
730 self.map_key = Some("$value".into());
731 seed.deserialize("$value".into_deserializer()).map(Some)
732 } else {
733 Ok(None)
734 }
735 }
736 SgmlEvent::Attribute { name, .. } => {
737 debug!("next key: {} (from attribute)", name);
738 seed.deserialize(name.as_ref().into_deserializer())
739 .map(Some)
740 }
741 SgmlEvent::CloseStartTag => {
742 self.de.advance()?;
743 continue;
744 }
745 SgmlEvent::OpenStartTag { name } => match self.content_strategy {
746 ContentStrategy::ElementsAreMapEntries => {
747 debug!("next key: {} (from tag name)", name);
748 self.map_key = Some(name.clone().into_owned().into());
749 seed.deserialize(name.as_ref().into_deserializer())
750 .map(Some)
751 }
752 ContentStrategy::ElementsAreDollarValue => {
753 debug!("next key: $value (for element {:?})", name);
754 seed.deserialize("$value".into_deserializer()).map(Some)
755 }
756 ContentStrategy::TextOnly => unreachable!(),
757 },
758 SgmlEvent::Character(text) => {
759 let text = mem::take(text);
760 self.de.advance()?;
761 if let Some(value_acc) = &mut self.text_content {
762 value_acc.push_cow(text);
763 }
764 continue;
765 }
766 SgmlEvent::ProcessingInstruction(_)
767 | SgmlEvent::MarkupDeclaration { .. }
768 | SgmlEvent::MarkedSection { .. } => unreachable!(),
769 };
770 }
771 }
772
773 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
774 where
775 V: de::DeserializeSeed<'de>,
776 {
777 trace!("next_value_seed (key={:?})", self.map_key);
778 self.de.check_stack_size(self.stack_size);
779
780 if self.next_entry_is_dollarvalue {
781 self.de.accumulated_text = Some(self.text_content.take().unwrap().into_cow());
782 let value = seed.deserialize(&mut *self.de)?;
783 self.de.accumulated_text = None;
784 Ok(value)
785 } else if let Ok(SgmlEvent::Attribute { .. }) = self.de.peek() {
786 seed.deserialize(&mut *self.de)
787 } else {
788 self.de.map_key = self.map_key.take();
789 let value = seed.deserialize(&mut *self.de)?;
790 self.de.map_key = None;
791 Ok(value)
792 }
793 }
794}
795
796struct SeqAccess<'de, 'r> {
797 de: &'r mut SgmlDeserializer<'de>,
798 stack_size: usize,
799 tag_name: Option<Rc<str>>,
800}
801
802impl<'de, 'r> SeqAccess<'de, 'r> {
803 fn new(de: &'r mut SgmlDeserializer<'de>, tag_name: Option<Rc<str>>) -> Self {
804 let stack_size = de.stack.len();
805 Self {
806 de,
807 stack_size,
808 tag_name,
809 }
810 }
811}
812
813impl<'de, 'r> de::SeqAccess<'de> for SeqAccess<'de, 'r> {
814 type Error = DeserializationError;
815
816 fn next_element_seed<T: de::DeserializeSeed<'de>>(
817 &mut self,
818 seed: T,
819 ) -> Result<Option<T::Value>, Self::Error> {
820 self.de.check_stack_size(self.stack_size);
821
822 loop {
823 match self.de.peek()? {
824 SgmlEvent::OpenStartTag { name } => match &self.tag_name {
825 Some(expected_tag) if name.as_ref() != expected_tag.as_ref() => {
826 return Ok(None)
827 }
828 _ => {
829 if self.de.map_key != self.tag_name {
830 self.de.map_key = self.tag_name.clone();
831 }
832 return Ok(Some(seed.deserialize(&mut *self.de)?));
833 }
834 },
835 SgmlEvent::Character(text) if text.is_empty() => self.de.advance()?,
836 _ => return Ok(None),
837 };
838 }
839 }
840}
841
842struct EnumAccess<'de, 'r> {
843 de: &'r mut SgmlDeserializer<'de>,
844 use_tag_name_for_variant: bool,
845}
846
847impl<'de, 'r> EnumAccess<'de, 'r> {
848 fn new(de: &'r mut SgmlDeserializer<'de>, use_tag_name_for_variant: bool) -> Self {
849 Self {
850 de,
851 use_tag_name_for_variant,
852 }
853 }
854}
855
856impl<'de, 'r> de::EnumAccess<'de> for EnumAccess<'de, 'r> {
857 type Error = DeserializationError;
858 type Variant = Self;
859
860 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), DeserializationError>
861 where
862 V: de::DeserializeSeed<'de>,
863 {
864 trace!("variant_seed");
865 let name = if self.use_tag_name_for_variant {
866 debug!("using tag name for enum variant");
867 let name = self.de.expect_start_tag()?.as_ref();
868 seed.deserialize(name.into_deserializer())
869 } else {
870 debug!("using text content for enum variant");
871 seed.deserialize(&mut *self.de)
872 }?;
873 Ok((name, self))
874 }
875}
876
877impl<'de, 'r> de::VariantAccess<'de> for EnumAccess<'de, 'r> {
878 type Error = DeserializationError;
879
880 fn unit_variant(self) -> Result<(), Self::Error> {
881 trace!("unit_variant");
882 if self.use_tag_name_for_variant {
883 self.de.push_elt()?;
884 self.de.pop_elt()?;
885 }
886 Ok(())
887 }
888
889 fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(
890 self,
891 seed: T,
892 ) -> Result<T::Value, Self::Error> {
893 trace!("newtype_variant");
894 seed.deserialize(self.de)
895 }
896
897 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
898 where
899 V: de::Visitor<'de>,
900 {
901 trace!("tuple_variant({} items)", len);
902 if self.use_tag_name_for_variant {
903 self.de.map_key = Some(self.de.expect_start_tag()?.clone().into_owned().into());
904 }
905 self.de.deserialize_seq(visitor)
906 }
907
908 fn struct_variant<V>(
909 self,
910 fields: &'static [&'static str],
911 visitor: V,
912 ) -> Result<V::Value, Self::Error>
913 where
914 V: de::Visitor<'de>,
915 {
916 trace!("struct_variant");
917 self.de.do_map(visitor, fields.contains(&"$value"))
918 }
919}
920
921#[derive(Debug)]
922struct PeekContentType {
923 contains_text: bool,
924 contains_child_elements: bool,
925}