Skip to main content

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}