Skip to main content

qubit_json/value/
duplicate_key_rejecting_json_value.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Deserializes JSON values while rejecting duplicate object keys.
9
10use serde::Deserialize;
11use serde::Deserializer;
12use serde::de::DeserializeSeed;
13use serde_json::Value;
14
15mod duplicate_key_rejecting_json_value_seed;
16mod internal;
17
18pub use duplicate_key_rejecting_json_value_seed::DuplicateKeyRejectingJsonValueSeed;
19
20/// A JSON value whose deserialization rejects duplicate object keys.
21///
22/// This wrapper is useful for document formats where accepting the usual
23/// last-key-wins object behavior would make the input ambiguous. It preserves
24/// serde_json's standard `i64`, `u64`, and finite `f64` number representation
25/// while recursively validating every object. For raw JSON text, use
26/// [`crate::decode::JsonDecoder`] when the crate's explicit numeric range
27/// contract must be enforced before deserialization.
28///
29/// # Examples
30///
31/// ```
32/// use qubit_json::value::DuplicateKeyRejectingJsonValue;
33///
34/// let value: DuplicateKeyRejectingJsonValue = serde_json::from_str(r#"{"ok":true}"#)?;
35/// assert_eq!(value.into_inner()["ok"], true);
36/// # Ok::<(), serde_json::Error>(())
37/// ```
38#[derive(Debug, PartialEq)]
39pub struct DuplicateKeyRejectingJsonValue(
40    /// Fully materialized value that passed duplicate-key validation.
41    Value,
42);
43
44impl DuplicateKeyRejectingJsonValue {
45    /// Returns the validated JSON value.
46    ///
47    /// # Returns
48    ///
49    /// The owned serde_json value constructed during deserialization.
50    #[must_use]
51    #[inline(always)]
52    pub fn into_inner(self) -> Value {
53        self.0
54    }
55}
56
57impl<'de> Deserialize<'de> for DuplicateKeyRejectingJsonValue {
58    /// Deserializes JSON recursively while rejecting duplicate object keys.
59    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60    where
61        D: Deserializer<'de>,
62    {
63        DuplicateKeyRejectingJsonValueSeed::new().deserialize(deserializer)
64    }
65}