Coverage Report

Created: 2025-10-31 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/quick-xml-0.38.3/src/de/var.rs
Line
Count
Source
1
use crate::{
2
    de::key::QNameDeserializer,
3
    de::map::ElementMapAccess,
4
    de::resolver::EntityResolver,
5
    de::simple_type::SimpleTypeDeserializer,
6
    de::{DeEvent, Deserializer, XmlRead, TEXT_KEY},
7
    errors::serialize::DeError,
8
};
9
use serde::de::value::BorrowedStrDeserializer;
10
use serde::de::{self, DeserializeSeed, Deserializer as _, Visitor};
11
12
/// An enum access
13
pub struct EnumAccess<'de, 'd, R, E>
14
where
15
    R: XmlRead<'de>,
16
    E: EntityResolver,
17
{
18
    de: &'d mut Deserializer<'de, R, E>,
19
}
20
21
impl<'de, 'd, R, E> EnumAccess<'de, 'd, R, E>
22
where
23
    R: XmlRead<'de>,
24
    E: EntityResolver,
25
{
26
0
    pub fn new(de: &'d mut Deserializer<'de, R, E>) -> Self {
27
0
        EnumAccess { de }
28
0
    }
29
}
30
31
impl<'de, 'd, R, E> de::EnumAccess<'de> for EnumAccess<'de, 'd, R, E>
32
where
33
    R: XmlRead<'de>,
34
    E: EntityResolver,
35
{
36
    type Error = DeError;
37
    type Variant = VariantAccess<'de, 'd, R, E>;
38
39
0
    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
40
0
    where
41
0
        V: DeserializeSeed<'de>,
42
    {
43
0
        let (name, is_text) = match self.de.peek()? {
44
0
            DeEvent::Start(e) => (seed.deserialize(QNameDeserializer::from_elem(e)?)?, false),
45
            DeEvent::Text(_) => (
46
0
                seed.deserialize(BorrowedStrDeserializer::<DeError>::new(TEXT_KEY))?,
47
                true,
48
            ),
49
            // SAFETY: The reader is guaranteed that we don't have unmatched tags
50
            // If we here, then our deserializer has a bug
51
0
            DeEvent::End(e) => unreachable!("{:?}", e),
52
0
            DeEvent::Eof => return Err(DeError::UnexpectedEof),
53
        };
54
0
        Ok((
55
0
            name,
56
0
            VariantAccess {
57
0
                de: self.de,
58
0
                is_text,
59
0
            },
60
0
        ))
61
0
    }
62
}
63
64
pub struct VariantAccess<'de, 'd, R, E>
65
where
66
    R: XmlRead<'de>,
67
    E: EntityResolver,
68
{
69
    de: &'d mut Deserializer<'de, R, E>,
70
    /// `true` if variant should be deserialized from a textual content
71
    /// and `false` if from tag
72
    is_text: bool,
73
}
74
75
impl<'de, 'd, R, E> de::VariantAccess<'de> for VariantAccess<'de, 'd, R, E>
76
where
77
    R: XmlRead<'de>,
78
    E: EntityResolver,
79
{
80
    type Error = DeError;
81
82
0
    fn unit_variant(self) -> Result<(), Self::Error> {
83
0
        match self.de.next()? {
84
            // Consume subtree
85
0
            DeEvent::Start(e) => self.de.read_to_end(e.name()),
86
            // Does not needed to deserialize using SimpleTypeDeserializer, because
87
            // it returns `()` when `deserialize_unit()` is requested
88
0
            DeEvent::Text(_) => Ok(()),
89
            // SAFETY: the other events are filtered in `variant_seed()`
90
0
            _ => unreachable!("Only `Start` or `Text` events are possible here"),
91
        }
92
0
    }
93
94
0
    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
95
0
    where
96
0
        T: DeserializeSeed<'de>,
97
    {
98
0
        if self.is_text {
99
0
            match self.de.next()? {
100
0
                DeEvent::Text(e) => seed.deserialize(SimpleTypeDeserializer::from_text_content(e)),
101
                // SAFETY: the other events are filtered in `variant_seed()`
102
0
                _ => unreachable!("Only `Text` events are possible here"),
103
            }
104
        } else {
105
0
            seed.deserialize(self.de)
106
        }
107
0
    }
108
109
0
    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
110
0
    where
111
0
        V: Visitor<'de>,
112
    {
113
0
        if self.is_text {
114
0
            match self.de.next()? {
115
0
                DeEvent::Text(e) => {
116
0
                    SimpleTypeDeserializer::from_text_content(e).deserialize_tuple(len, visitor)
117
                }
118
                // SAFETY: the other events are filtered in `variant_seed()`
119
0
                _ => unreachable!("Only `Text` events are possible here"),
120
            }
121
        } else {
122
0
            self.de.deserialize_tuple(len, visitor)
123
        }
124
0
    }
125
126
0
    fn struct_variant<V>(
127
0
        self,
128
0
        fields: &'static [&'static str],
129
0
        visitor: V,
130
0
    ) -> Result<V::Value, Self::Error>
131
0
    where
132
0
        V: Visitor<'de>,
133
    {
134
0
        match self.de.next()? {
135
0
            DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.de, e, fields)?),
136
0
            DeEvent::Text(e) => {
137
0
                SimpleTypeDeserializer::from_text_content(e).deserialize_struct("", fields, visitor)
138
            }
139
            // SAFETY: the other events are filtered in `variant_seed()`
140
0
            _ => unreachable!("Only `Start` or `Text` events are possible here"),
141
        }
142
0
    }
143
}