Skip to main content

jsonp/
visitor.rs

1use {
2    super::RawJson,
3    serde::de::{Deserialize, Error, IgnoredAny, MapAccess, SeqAccess, Visitor},
4    std::{fmt, str::FromStr},
5};
6
7/// Lazily attempts to parse a key / index only once requested by a
8/// deserializer. This allows users to pass in "numeric" map key
9/// pointer segments and have them deserialize as expected.
10///
11/// However, it does open the door to unexpected deserialization,
12/// if the user was expecting a pointer segment to correspond to a
13/// map with a numeric key and instead somehow got an array.
14#[derive(Debug, Clone, Copy)]
15pub(crate) struct LazyVisitor<'p> {
16    k_or_idx: &'p str,
17}
18
19impl<'p> LazyVisitor<'p> {
20    pub(crate) fn new(k_or_idx: &'p str) -> Self {
21        Self { k_or_idx }
22    }
23}
24
25impl<'de, 'p> Visitor<'de> for LazyVisitor<'p> {
26    type Value = &'de RawJson;
27
28    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
29        write!(
30            formatter,
31            "a map or array including the key or index: {}",
32            self.k_or_idx
33        )
34    }
35
36    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
37    where
38        A: MapAccess<'de>,
39    {
40        internal_visit_map(self.k_or_idx, map)
41    }
42
43    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
44    where
45        A: SeqAccess<'de>,
46    {
47        let index = u64::from_str(self.k_or_idx)
48            .map_err(|_| Error::custom(format!("not an indexable number: {}", self.k_or_idx)))?;
49
50        internal_visit_seq(index, seq)
51    }
52}
53
54#[derive(Debug, Clone, Copy)]
55pub(crate) struct MapVisitor<'p> {
56    key: &'p str,
57}
58
59impl<'p> MapVisitor<'p> {
60    pub(crate) fn new(key: &'p str) -> Self {
61        Self { key }
62    }
63}
64
65impl<'de, 'p> Visitor<'de> for MapVisitor<'p> {
66    type Value = &'de RawJson;
67
68    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
69        write!(formatter, "a map including the key: {}", self.key)
70    }
71
72    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
73    where
74        A: MapAccess<'de>,
75    {
76        internal_visit_map(self.key, map)
77    }
78}
79
80#[derive(Debug, Clone, Copy)]
81pub(crate) struct ArrayVisitor {
82    index: u64,
83}
84
85impl ArrayVisitor {
86    pub(crate) fn new(index: u64) -> Self {
87        Self { index }
88    }
89}
90
91impl<'de> Visitor<'de> for ArrayVisitor {
92    type Value = &'de RawJson;
93
94    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
95        write!(formatter, "an array including the index: {}", self.index)
96    }
97
98    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
99    where
100        A: SeqAccess<'de>,
101    {
102        internal_visit_seq(self.index, seq)
103    }
104}
105
106fn internal_visit_map<'de, A, T>(target: &str, map: A) -> Result<T, A::Error>
107where
108    T: Deserialize<'de>,
109    A: MapAccess<'de>,
110{
111    let mut map = map;
112    let mut out = None;
113
114    // Serde expects each call to next_key be followed by a
115    // call to next_value before another call to next_key, however
116    // we only want to spend effort deserializing if this is the
117    // expected key, otherwise we forward to IgnoredAny.
118    while let Some(k) = map.next_key::<&str>()? {
119        match k == target {
120            false => {
121                map.next_value::<IgnoredAny>()?;
122            }
123            true => {
124                out = Some(map.next_value()?);
125                break;
126            }
127        }
128    }
129
130    // It is a logic error to not fully walk a given map, however we have
131    // already found our value here so we ignore everything except potential
132    // errors in the stream.
133    while let Some((_k, _v)) = map.next_entry::<IgnoredAny, IgnoredAny>()? {}
134
135    out.ok_or_else(|| Error::custom(format!("unable to locate a value with the key: {}", target)))
136}
137
138fn internal_visit_seq<'de, A, T>(target: u64, seq: A) -> Result<T, A::Error>
139where
140    T: Deserialize<'de>,
141    A: SeqAccess<'de>,
142{
143    let mut seq = seq;
144    let mut count = 0;
145
146    // Ignore all elements before our target
147    while count < target {
148        if seq.next_element::<IgnoredAny>()?.is_none() {
149            break;
150        }
151        count += 1;
152    }
153
154    let out = seq.next_element()?;
155
156    // It is a logic error to not fully walk a given sequence, however we
157    // have already found our value, so we ignore everything except potential
158    // errors.
159    while let Some(_val) = seq.next_element::<IgnoredAny>()? {}
160
161    out.ok_or_else(|| {
162        Error::custom(format!(
163            "unable to locate a value with the index: {}",
164            target
165        ))
166    })
167}