1use super::{
2 child::ChildDeserializer,
3 plain::PlainTextDeserializer,
4 reader::{Attribute, ChildReader, Event, Reader},
5};
6use crate::{
7 config::{CONTENT, TEXT},
8 error::{Error, Result},
9};
10use log::trace;
11use serde::de::IntoDeserializer;
12use std::{io::Read, iter::Peekable};
13
14pub struct MapAccess<'a, R: Read> {
15 reader: ChildReader<'a, R>,
16 attributes: Peekable<std::vec::IntoIter<Attribute>>,
17 fields: &'static [&'static str],
18}
19
20impl<'a, R: Read> MapAccess<'a, R> {
21 pub fn new_map(reader: ChildReader<'a, R>) -> Self {
22 Self {
23 reader,
24 attributes: vec![].into_iter().peekable(),
25 fields: &[],
26 }
27 }
28
29 pub fn new_struct(
30 reader: ChildReader<'a, R>,
31 attributes: Vec<Attribute>,
32 fields: &'static [&'static str],
33 ) -> Self {
34 Self {
35 reader,
36 attributes: attributes.into_iter().peekable(),
37 fields,
38 }
39 }
40
41 fn is_content(&self, element_name: &str) -> bool {
42 !self.fields.contains(&element_name) && self.fields.contains(&CONTENT)
43 }
44}
45
46impl<'de, R: Read> serde::de::MapAccess<'de> for MapAccess<'_, R> {
47 type Error = Error;
48
49 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
50 where
51 K: serde::de::DeserializeSeed<'de>,
52 {
53 trace!("next map/struct key");
54 if let Some(attr) = self.attributes.peek() {
55 trace!("attribute {}", attr.qname());
56 seed.deserialize(format!("@{}", attr.qname()).into_deserializer())
57 .map(Some)
58 } else {
59 match self.reader.peek()? {
60 Event::StartElement(element) => {
61 let element_name = element.qname();
62 if self.is_content(&element_name) {
63 trace!("#content");
64 seed.deserialize(CONTENT.into_deserializer()).map(Some)
65 } else {
66 trace!("element '{}'", element_name);
67 seed.deserialize(element_name.as_str().into_deserializer())
68 .map(Some)
69 }
70 }
71 Event::Text(_) => {
72 trace!("{}", TEXT);
73 seed.deserialize(TEXT.into_deserializer()).map(Some)
74 }
75 _ => Ok(None),
76 }
77 }
78 }
79
80 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
81 where
82 V: serde::de::DeserializeSeed<'de>,
83 {
84 if let Some(attr) = self.attributes.next() {
85 seed.deserialize(PlainTextDeserializer::new(&attr.value))
86 } else {
87 match self.reader.peek()? {
88 Event::StartElement(element) => {
89 let element_name = element.qname();
90 if self.is_content(&element_name) {
91 seed.deserialize(ChildDeserializer::new(self.reader.child()))
92 } else {
93 seed.deserialize(ChildDeserializer::new_with_element_name(
94 self.reader.child(),
95 element_name,
96 ))
97 }
98 }
99 Event::Text(_) => {
100 seed.deserialize(PlainTextDeserializer::new(&self.reader.chars()?))
101 }
102 event => Err(Error::Unexpected {
103 expected: "start of element or text",
104 but_got: event.to_string(),
105 }),
106 }
107 }
108 }
109}