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}