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}