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    /// Serializes the protected JSON tree through the supplied Serde backend.
29    ///
30    /// The traversal grows the stack when needed. Errors from scalar,
31    /// container, or nested serializer operations are returned unchanged.
32    ///
33    /// # Parameters
34    ///
35    /// * `serializer` - Backend that receives the serialized JSON value.
36    ///
37    /// # Type Parameters
38    ///
39    /// * `S` - Serde serializer that defines the output and error types.
40    ///
41    /// # Returns
42    ///
43    /// The value produced by the serializer on success.
44    ///
45    /// # Errors
46    ///
47    /// Returns the backend's error if any serialization operation fails.
48    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49    where
50        S: Serializer,
51    {
52        serialize_value(self.as_value(), serializer)
53    }
54}
55
56/// Serializes a JSON value recursively while growing the stack for this bridge.
57///
58/// `value` is borrowed for the duration of the serializer calls. The stacker
59/// guard covers this bridge’s recursive traversal, but cannot control recursive
60/// work performed internally by the caller’s serializer. Child and serializer
61/// errors propagate unchanged.
62///
63/// # Parameters
64///
65/// * `value` - JSON subtree to serialize without taking ownership.
66/// * `serializer` - Destination Serde serializer.
67///
68/// # Type Parameters
69///
70/// * `S` - Serde serializer that defines the output and error types.
71///
72/// # Returns
73///
74/// The serializer’s successful output.
75///
76/// # Errors
77///
78/// Returns the serializer’s error from a scalar, child, or container operation.
79pub(in crate::value) fn serialize_value<S>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
80where
81    S: Serializer,
82{
83    stacker::maybe_grow(32 * 1024, 1024 * 1024, || match value {
84        Value::Null => serializer.serialize_unit(),
85        Value::Bool(value) => serializer.serialize_bool(*value),
86        Value::Number(value) => value.serialize(serializer),
87        Value::String(value) => serializer.serialize_str(value),
88        Value::Array(values) => {
89            let mut seq = serializer.serialize_seq(Some(values.len()))?;
90            for child in values {
91                seq.serialize_element(&Nested(child))?;
92            }
93            seq.end()
94        }
95        Value::Object(values) => {
96            let mut map = serializer.serialize_map(Some(values.len()))?;
97            for (key, child) in values {
98                map.serialize_entry(key, &Nested(child))?;
99            }
100            map.end()
101        }
102    })
103}
104
105impl<'de> Deserialize<'de> for SafeJsonValue {
106    /// Deserializes a JSON value through the supplied Serde backend.
107    ///
108    /// The traversal grows the stack when needed. Duplicate object keys are
109    /// rejected by the visitor; the backend's own errors are propagated.
110    ///
111    /// # Parameters
112    ///
113    /// * `deserializer` - Backend providing the input value.
114    ///
115    /// # Type Parameters
116    ///
117    /// * `D` - Serde deserializer that defines the input and error types.
118    ///
119    /// # Returns
120    ///
121    /// A protected owner for the deserialized JSON tree.
122    ///
123    /// # Errors
124    ///
125    /// Returns the backend or visitor error if decoding fails.
126    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
127    where
128        D: Deserializer<'de>,
129    {
130        stacker::maybe_grow(32 * 1024, 1024 * 1024, || {
131            deserializer.deserialize_any(ValueVisitor).map(SafeJsonValue::new)
132        })
133    }
134}