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    fn eq(&self, other: &JsonValueRef<'b>) -> bool {
91        values_equal(self.value, other.value)
92    }
93}
94
95impl Eq for JsonValueRef<'_> {}
96
97impl fmt::Debug for JsonValueRef<'_> {
98    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
99        debug_value(self.value, formatter)
100    }
101}
102
103impl Serialize for JsonValueRef<'_> {
104    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
105    where
106        S: Serializer,
107    {
108        super::safe_json_serde::serialize_value(self.value, serializer)
109    }
110}