Skip to main content

deser_core/de/
duplicates.rs

1use crate::State;
2use crate::error::{Error, ErrorKind};
3use alloc::format;
4use alloc::string::String;
5
6/// What happens if a key is given more than once.
7///
8/// JSON objects can contain the same key more than once and query strings
9/// commonly repeat keys.  Where a single value is expected (the field of a
10/// struct or an entry of a map) the policy decides what happens.  It's an
11/// extension value in the [`State`] (see [`set`](Self::set)).  The default is
12/// [`Error`](Self::Error): if the same key could mean different values to
13/// different parsers (a proxy might use the first value, the application the
14/// last) the input is rejected.
15///
16/// ```
17/// use std::collections::BTreeMap;
18/// use deser::de::{DeserializeDriver, DuplicateKeys};
19/// use deser::Event;
20///
21/// let mut out = None::<BTreeMap<String, u32>>;
22/// let mut driver = DeserializeDriver::new(&mut out);
23/// DuplicateKeys::Error.set(driver.state_mut());
24/// driver.emit(Event::map_start()).unwrap();
25/// for value in [1u64, 2] {
26///     driver.emit("a").unwrap();
27///     driver.emit(value).unwrap();
28/// }
29/// let err = driver.emit(Event::MapEnd).unwrap_err();
30/// assert_eq!(err.message(), "duplicate key in map");
31/// ```
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
33#[non_exhaustive]
34pub enum DuplicateKeys {
35    /// The last value is used.
36    Last,
37    /// The first value is used, later ones are ignored.
38    First,
39    /// Duplicate keys are rejected.
40    #[default]
41    Error,
42}
43
44impl DuplicateKeys {
45    /// Returns the policy of a deserialization.
46    #[inline]
47    pub fn of(state: &State) -> DuplicateKeys {
48        state.get::<DuplicateKeys>().copied().unwrap_or_default()
49    }
50
51    /// Sets the policy of a deserialization.
52    #[inline]
53    pub fn set(self, state: &mut State) {
54        *state.get_mut::<DuplicateKeys>() = self;
55    }
56
57    /// Decides if a duplicate value is used.
58    ///
59    /// Returns `Ok(true)` if the value replaces the previous one, `Ok(false)`
60    /// if it's ignored.  The name is used for the error.
61    #[cold]
62    pub(crate) fn resolve(self, what: impl FnOnce() -> String) -> Result<bool, Error> {
63        match self {
64            DuplicateKeys::Last => Ok(true),
65            DuplicateKeys::First => Ok(false),
66            DuplicateKeys::Error => Err(Error::new(ErrorKind::Unexpected, what())),
67        }
68    }
69}
70
71/// Marks a field of a struct as seen.
72///
73/// Returns `true` if it was seen before.
74#[cfg(feature = "derive")]
75#[inline(always)]
76pub fn mark_seen(seen: &mut [u64], index: usize) -> bool {
77    let (word, bit) = (index / 64, 1u64 << (index % 64));
78    let seen_before = seen[word] & bit != 0;
79    seen[word] |= bit;
80    seen_before
81}
82
83/// Returns `true` if the field with the index was seen.
84#[cfg(feature = "derive")]
85pub(crate) fn is_seen(seen: &[u64], index: usize) -> bool {
86    seen[index / 64] & (1u64 << (index % 64)) != 0
87}
88
89/// Decides if the value of a field given more than once is used.
90///
91/// Returns `Ok(true)` if the value replaces the previous one.
92#[cold]
93pub fn duplicate_field(name: &str, state: &State) -> Result<bool, Error> {
94    DuplicateKeys::of(state).resolve(|| format!("duplicate field `{}`", name))
95}