Skip to main content

qubit_json/value/
safe_json_serde.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//! Protected Serde interoperability for [`super::SafeJsonValue`].
9//!
10//! Deserialization rejects duplicate object keys and non-finite numbers. Values
11//! are assembled through the guarded builder, so an error cannot expose a
12//! partially built `SafeJsonValue`. Serialization delegates recursively to the
13//! caller's Serde serializer and therefore preserves that serializer's errors.
14
15use serde::Deserialize;
16use serde::Deserializer;
17use serde::Serialize;
18use serde::Serializer;
19use serde::ser::SerializeMap;
20use serde::ser::SerializeSeq;
21use serde_json::Value;
22
23use super::SafeJsonValue;
24use super::internal::Nested;
25use super::internal::ValueVisitor;
26
27impl Serialize for SafeJsonValue {
28    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29    where
30        S: Serializer,
31    {
32        serialize_value(self.as_value(), serializer)
33    }
34}
35
36/// Serializes a JSON value recursively while growing the stack for this bridge.
37///
38/// `value` is borrowed for the duration of the serializer calls. The stacker
39/// guard covers this bridge’s recursive traversal, but cannot control recursive
40/// work performed internally by the caller’s serializer. Child and serializer
41/// errors propagate unchanged.
42///
43/// # Parameters
44///
45/// * `value` - JSON subtree to serialize without taking ownership.
46/// * `serializer` - Destination Serde serializer.
47///
48/// # Returns
49///
50/// The serializer’s successful output.
51///
52/// # Errors
53///
54/// Returns the serializer’s error from a scalar, child, or container operation.
55pub(in crate::value) fn serialize_value<S>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
56where
57    S: Serializer,
58{
59    stacker::maybe_grow(32 * 1024, 1024 * 1024, || match value {
60        Value::Null => serializer.serialize_unit(),
61        Value::Bool(value) => serializer.serialize_bool(*value),
62        Value::Number(value) => value.serialize(serializer),
63        Value::String(value) => serializer.serialize_str(value),
64        Value::Array(values) => {
65            let mut seq = serializer.serialize_seq(Some(values.len()))?;
66            for child in values {
67                seq.serialize_element(&Nested(child))?;
68            }
69            seq.end()
70        }
71        Value::Object(values) => {
72            let mut map = serializer.serialize_map(Some(values.len()))?;
73            for (key, child) in values {
74                map.serialize_entry(key, &Nested(child))?;
75            }
76            map.end()
77        }
78    })
79}
80
81impl<'de> Deserialize<'de> for SafeJsonValue {
82    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83    where
84        D: Deserializer<'de>,
85    {
86        stacker::maybe_grow(32 * 1024, 1024 * 1024, || {
87            deserializer.deserialize_any(ValueVisitor).map(SafeJsonValue::new)
88        })
89    }
90}