qubit_json/value/json_value_ref.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// =============================================================================
8use std::fmt;
9
10use serde::Serialize;
11use serde::Serializer;
12use serde_json::Value;
13
14use super::internal::debug_value;
15use super::internal::values_equal;
16
17/// An immutable, borrowed view of a JSON value.
18///
19/// Constructing a view copies only a reference. Equality and debug formatting
20/// use explicit work stacks, which may allocate. Serialization uses the same
21/// `stacker`-backed recursive Serde bridge as
22/// [`SafeJsonValue`](super::SafeJsonValue). The bridge can grow the stack for
23/// library-side recursive calls, but the selected serializer may still impose
24/// its own recursion limits; it does not promise an exact memory bound or
25/// support unlimited depth. The view does not protect the borrowed tree's
26/// destruction when its owner is dropped.
27///
28/// # Examples
29///
30/// ```
31/// use qubit_json::value::{JsonValueRef, SafeJsonValue};
32///
33/// let owner = SafeJsonValue::new(serde_json::json!({"items": [1, 2]}));
34/// let view = JsonValueRef::new(owner.as_value());
35/// assert_eq!(
36/// serde_json::to_vec(&view).unwrap(),
37/// serde_json::to_vec(&owner).unwrap()
38/// );
39/// ```
40///
41/// The view cannot outlive its borrowed owner:
42///
43/// ```compile_fail
44/// use qubit_json::value::{JsonValueRef, SafeJsonValue};
45/// let view = {
46/// let owner = SafeJsonValue::new(serde_json::json!([1]));
47/// JsonValueRef::new(owner.as_value())
48/// };
49/// println!("{view:?}");
50/// ```
51#[derive(Clone, Copy)]
52pub struct JsonValueRef<'a> {
53 /// The borrowed tree; its owner must outlive this view.
54 value: &'a Value,
55}
56
57impl<'a> JsonValueRef<'a> {
58 /// Borrows a JSON tree without copying, traversing, or admitting it to a
59 /// budget.
60 ///
61 /// # Parameters
62 ///
63 /// * `value` - Tree that must remain alive for the lifetime of this view.
64 ///
65 /// # Returns
66 ///
67 /// A read-only view tied to the supplied borrow. Construction does not
68 /// allocate.
69 #[must_use]
70 #[inline]
71 pub const fn new(value: &'a Value) -> Self {
72 Self { value }
73 }
74
75 /// Returns the borrowed JSON value, preserving its original owner lifetime.
76 ///
77 /// Consuming this view does not extend the lifetime of the underlying tree.
78 ///
79 /// # Returns
80 ///
81 /// The JSON tree borrowed by this view.
82 #[must_use]
83 #[inline]
84 pub const fn as_value(self) -> &'a Value {
85 self.value
86 }
87}
88
89impl<'a, 'b> PartialEq<JsonValueRef<'b>> for JsonValueRef<'a> {
90 /// Compares the referenced JSON trees without requiring matching borrow
91 /// lifetimes.
92 ///
93 /// Equality uses an explicit work stack, which may allocate for nested
94 /// values.
95 ///
96 /// # Parameters
97 ///
98 /// * `other` - View of the JSON tree to compare with this one.
99 ///
100 /// # Returns
101 ///
102 /// `true` when both referenced trees are equal; otherwise, `false`.
103 fn eq(&self, other: &JsonValueRef<'b>) -> bool {
104 values_equal(self.value, other.value)
105 }
106}
107
108impl Eq for JsonValueRef<'_> {}
109
110impl fmt::Debug for JsonValueRef<'_> {
111 /// Formats the referenced JSON tree using the safe recursive formatting
112 /// bridge.
113 ///
114 /// Formatting may allocate an explicit work stack for nested values.
115 ///
116 /// # Parameters
117 ///
118 /// * `formatter` - Formatter that receives the JSON tree's debug
119 /// representation.
120 ///
121 /// # Returns
122 ///
123 /// `Ok(())` when formatting succeeds, or the formatting error reported by
124 /// the formatter.
125 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
126 debug_value(self.value, formatter)
127 }
128}
129
130impl Serialize for JsonValueRef<'_> {
131 /// Serializes the referenced JSON tree through the stack-growing Serde
132 /// bridge.
133 ///
134 /// The bridge supports library-side recursive calls, while the serializer
135 /// may still impose its own recursion limits.
136 ///
137 /// # Type Parameters
138 ///
139 /// * `S` - Serializer that receives the JSON tree's serialized
140 /// representation.
141 ///
142 /// # Parameters
143 ///
144 /// * `serializer` - Serializer used to encode the borrowed JSON tree.
145 ///
146 /// # Returns
147 ///
148 /// The value produced by the serializer after encoding succeeds.
149 ///
150 /// # Errors
151 ///
152 /// Returns the serializer's error if encoding the tree fails.
153 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
154 where
155 S: Serializer,
156 {
157 super::safe_json_serde::serialize_value(self.value, serializer)
158 }
159}