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}