Skip to main content

qubit_budget/json/encode/
json_encode_limits.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//! Defines JSON encoding limits.
9
10use super::JsonEncodeLimitsBuilder;
11use crate::json::JsonResource;
12use crate::json::JsonValueLimits;
13use crate::resource::ResourceLimit;
14use crate::resource::ResourceQuantity;
15
16/// Optional limits for one JSON encoding session.
17///
18/// # Type Parameters
19///
20/// * `R` - Caller-defined resource identity retained by limits and errors.
21/// * `Q` - Exact unsigned quantity used for measurements and accounting.
22///
23/// # Examples
24///
25/// ```
26/// use qubit_budget::json::JsonEncodeLimits;
27///
28/// let limits = JsonEncodeLimits::builder().max_output_bytes(128_usize).max_depth(4_usize).build();
29/// assert_eq!(limits.max_output_bytes(), Some(128));
30/// assert_eq!(limits.value_limits().max_depth(), Some(4));
31/// ```
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub struct JsonEncodeLimits<R = JsonResource, Q = usize>
34where
35    Q: ResourceQuantity,
36{
37    /// Optional maximum for bytes emitted by one JSON encoding session.
38    output: Option<ResourceLimit<R, Q>>,
39    /// Limits applied to the encoded JSON value and its structure.
40    value: JsonValueLimits<R, Q>,
41}
42
43impl<R, Q> Default for JsonEncodeLimits<R, Q>
44where
45    Q: ResourceQuantity,
46{
47    /// Creates encoding limits with every dimension unconfigured.
48    ///
49    /// # Returns
50    ///
51    /// Creates encoding limits with every dimension unconfigured.
52    fn default() -> Self {
53        Self::new()
54    }
55}
56
57impl<R, Q> JsonEncodeLimits<R, Q>
58where
59    Q: ResourceQuantity,
60{
61    /// Creates an empty encoding limit set with no configured resource limits.
62    ///
63    /// # Returns
64    ///
65    /// Creates an empty encoding limit set with no configured resource limits.
66    #[inline]
67    #[must_use]
68    pub const fn new() -> Self {
69        Self {
70            output: None,
71            value: JsonValueLimits::new(),
72        }
73    }
74
75    /// Creates a builder for JSON encoding limits.
76    ///
77    /// # Returns
78    ///
79    /// Creates a builder for JSON encoding limits.
80    #[inline]
81    #[must_use]
82    pub const fn builder() -> JsonEncodeLimitsBuilder<R, Q> {
83        JsonEncodeLimitsBuilder::new()
84    }
85
86    /// Converts these limits into a builder for further configuration.
87    ///
88    /// # Returns
89    ///
90    /// Converts these limits into a builder for further configuration.
91    #[inline]
92    #[must_use]
93    pub const fn into_builder(self) -> JsonEncodeLimitsBuilder<R, Q> {
94        JsonEncodeLimitsBuilder::from_limits(self)
95    }
96
97    /// Returns whether any encoding or nested value limit is configured.
98    ///
99    /// # Returns
100    ///
101    /// `true` when the output limit or at least one nested value limit is
102    /// configured; otherwise `false`.
103    #[must_use]
104    #[inline(always)]
105    pub const fn has_limits(&self) -> bool {
106        self.output.is_some() || self.value.has_limits()
107    }
108
109    /// Returns the complete output-byte limit, when configured.
110    ///
111    /// # Returns
112    ///
113    /// Returns the complete output-byte limit, when configured.
114    ///
115    /// `None` indicates that the corresponding limit or budget dimension is
116    /// unconfigured.
117    #[must_use]
118    #[inline(always)]
119    pub const fn output_bytes_limit(&self) -> Option<&ResourceLimit<R, Q>> {
120        self.output.as_ref()
121    }
122
123    /// Borrows the JSON value limits used for encoding.
124    ///
125    /// # Returns
126    ///
127    /// Borrows the JSON value limits used for encoding.
128    #[must_use]
129    #[inline(always)]
130    pub const fn value_limits(&self) -> &JsonValueLimits<R, Q> {
131        &self.value
132    }
133
134    /// Consumes these encoding limits and returns their JSON value limits.
135    ///
136    /// # Returns
137    ///
138    /// Consumes these encoding limits and returns their JSON value limits.
139    #[must_use]
140    #[inline]
141    pub fn into_value_limits(self) -> JsonValueLimits<R, Q> {
142        self.value
143    }
144
145    /// Returns the configured output-byte maximum.
146    ///
147    /// # Returns
148    ///
149    /// Returns the configured output-byte maximum.
150    ///
151    /// `None` indicates that the corresponding limit or budget dimension is
152    /// unconfigured.
153    #[must_use]
154    #[inline(always)]
155    pub const fn max_output_bytes(&self) -> Option<Q> {
156        match self.output.as_ref() {
157            Some(limit) => Some(limit.maximum()),
158            None => None,
159        }
160    }
161
162    /// Replaces the output-byte limit during builder composition.
163    ///
164    /// # Parameters
165    ///
166    /// * `limit` - Resource-bound output-byte limit to install.
167    pub(super) fn set_output_bytes_limit(&mut self, limit: ResourceLimit<R, Q>) {
168        self.output = Some(limit);
169    }
170
171    /// Replaces the JSON value limits during builder composition.
172    ///
173    /// # Parameters
174    ///
175    /// * `limits` - JSON value limits to apply during encoding.
176    pub(super) fn set_value_limits(&mut self, limits: JsonValueLimits<R, Q>) {
177        self.value = limits;
178    }
179}