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}