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, usually configured in the [`Context`](crate::Context)
12/// (or in the [`State`], see [`set`](Self::set)).  The default is
13/// [`Error`](Self::Error): if the same key could mean different values to
14/// different parsers (a proxy might use the first value, the application the
15/// last) the input is rejected.  Formats can have other defaults (query
16/// strings and environment variables use the last value), which the
17/// context overrides.
18///
19/// ```
20/// use std::collections::BTreeMap;
21/// use deser::de::DuplicateKeys;
22/// use deser::Context;
23///
24/// type Map = BTreeMap<String, u32>;
25///
26/// let input = r#"{"a": 1, "a": 2}"#;
27/// let err = deser_json::from_str::<Map>(input).unwrap_err();
28/// assert_eq!(err.message(), "duplicate key in map");
29///
30/// let config = deser_json::DeserializerConfig::builder()
31///     .context(Context::with(DuplicateKeys::Last))
32///     .build();
33/// assert_eq!(config.from_str::<Map>(input).unwrap()["a"], 2);
34/// ```
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
36#[non_exhaustive]
37pub enum DuplicateKeys {
38    /// The last value is used.
39    Last,
40    /// The first value is used, later ones are ignored.
41    First,
42    /// Duplicate keys are rejected.
43    #[default]
44    Error,
45}
46
47impl DuplicateKeys {
48    /// Returns the policy of a deserialization.
49    #[inline]
50    pub fn of(state: &State) -> DuplicateKeys {
51        state.get::<DuplicateKeys>().copied().unwrap_or_default()
52    }
53
54    /// Sets the policy of a deserialization.
55    #[inline]
56    pub fn set(self, state: &mut State) {
57        *state.get_mut::<DuplicateKeys>() = self;
58    }
59
60    /// Sets the policy unless the state or the context has one.
61    ///
62    /// Formats use this for their default (see [`State::set_default`]).
63    #[inline]
64    pub fn set_default(self, state: &mut State) {
65        state.set_default(self);
66    }
67
68    /// Decides if a duplicate value is used.
69    ///
70    /// Returns `Ok(true)` if the value replaces the previous one, `Ok(false)`
71    /// if it's ignored.  The name is used for the error.
72    #[cold]
73    pub(crate) fn resolve(self, what: impl FnOnce() -> String) -> Result<bool, Error> {
74        match self {
75            DuplicateKeys::Last => Ok(true),
76            DuplicateKeys::First => Ok(false),
77            DuplicateKeys::Error => Err(Error::new(ErrorKind::DuplicateKey, what())),
78        }
79    }
80}
81
82/// Marks a field of a struct as seen.
83///
84/// Returns `true` if it was seen before.
85#[cfg(feature = "derive")]
86#[inline(always)]
87pub(crate) fn mark_seen(seen: &mut [u64], index: usize) -> bool {
88    let (word, bit) = (index / 64, 1u64 << (index % 64));
89    let seen_before = seen[word] & bit != 0;
90    seen[word] |= bit;
91    seen_before
92}
93
94/// Returns `true` if the field with the index was seen.
95#[cfg(feature = "derive")]
96pub(crate) fn is_seen(seen: &[u64], index: usize) -> bool {
97    seen[index / 64] & (1u64 << (index % 64)) != 0
98}
99
100/// Decides if the value of a field given more than once is used.
101///
102/// Returns `Ok(true)` if the value replaces the previous one.
103#[cold]
104pub(crate) fn duplicate_field(name: &str, state: &State) -> Result<bool, Error> {
105    DuplicateKeys::of(state).resolve(|| format!("duplicate field `{}`", name))
106}