qubit_redact/policy/
redaction_limits.rs1use qubit_budget::StructureLimits;
12#[cfg(feature = "json")]
13use qubit_budget::json::JsonValueLimits;
14
15#[derive(Debug, Clone, Copy)]
17pub struct RedactionLimitsBuilder {
18 max_input_bytes: usize,
20 max_output_bytes: usize,
22 domain: StructureLimits,
24 #[cfg(feature = "json")]
26 json: JsonValueLimits,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct RedactionLimits {
43 max_input_bytes: usize,
45 max_output_bytes: usize,
47 domain: StructureLimits,
49 #[cfg(feature = "json")]
51 json: JsonValueLimits,
52}
53
54impl RedactionLimits {
55 #[must_use]
57 pub fn builder() -> RedactionLimitsBuilder {
58 RedactionLimitsBuilder::default()
59 }
60
61 #[must_use]
63 pub(crate) fn builder_from(base: &Self) -> RedactionLimitsBuilder {
64 RedactionLimitsBuilder {
65 max_input_bytes: base.max_input_bytes,
66 max_output_bytes: base.max_output_bytes,
67 domain: base.domain,
68 #[cfg(feature = "json")]
69 json: base.json,
70 }
71 }
72
73 #[must_use]
75 #[inline(always)]
76 pub(crate) const fn structural_limits(&self) -> StructureLimits {
77 self.domain
78 }
79
80 #[must_use]
82 #[inline(always)]
83 pub const fn max_input_bytes(&self) -> usize {
84 self.max_input_bytes
85 }
86
87 #[must_use]
89 #[inline(always)]
90 pub const fn max_output_bytes(&self) -> usize {
91 self.max_output_bytes
92 }
93
94 #[must_use]
96 #[inline(always)]
97 pub const fn max_depth(&self) -> Option<usize> {
98 self.domain.max_depth()
99 }
100
101 #[must_use]
103 #[inline(always)]
104 pub const fn max_nodes(&self) -> Option<usize> {
105 self.domain.max_nodes()
106 }
107
108 #[must_use]
110 #[inline(always)]
111 pub const fn max_collection_items(&self) -> Option<usize> {
112 self.domain.max_sequence_items()
113 }
114
115 #[must_use]
117 #[inline(always)]
118 pub const fn max_key_bytes(&self) -> Option<usize> {
119 self.domain.max_key_bytes()
120 }
121
122 pub(crate) fn validate(&self) -> Result<(), super::PolicyError> {
130 if self.max_output_bytes > isize::MAX as usize {
131 return Err(super::PolicyError::OutputLimitTooLarge {
132 maximum: self.max_output_bytes,
133 });
134 }
135 Ok(())
136 }
137
138 #[cfg(feature = "json")]
140 #[must_use]
141 #[inline(always)]
142 pub(crate) const fn json_limits(&self) -> JsonValueLimits {
143 self.json
144 }
145
146 #[cfg(feature = "json")]
148 #[must_use]
149 #[inline(always)]
150 pub const fn max_json_depth(&self) -> Option<usize> {
151 self.json.max_depth()
152 }
153
154 #[cfg(feature = "json")]
156 #[must_use]
157 #[inline(always)]
158 pub const fn max_json_nodes(&self) -> Option<usize> {
159 self.json.max_nodes()
160 }
161
162 #[cfg(feature = "json")]
164 #[must_use]
165 #[inline(always)]
166 pub const fn max_json_collection_items(&self) -> Option<usize> {
167 self.json.max_sequence_items()
168 }
169
170 #[cfg(feature = "json")]
172 #[must_use]
173 #[inline(always)]
174 pub const fn max_json_key_bytes(&self) -> Option<usize> {
175 self.json.max_key_bytes()
176 }
177
178 #[cfg(feature = "json")]
180 #[must_use]
181 #[inline(always)]
182 pub const fn max_json_string_bytes(&self) -> Option<usize> {
183 self.json.max_string_bytes()
184 }
185
186 #[cfg(feature = "json")]
188 #[must_use]
189 #[inline(always)]
190 pub const fn max_json_number_bytes(&self) -> Option<usize> {
191 self.json.max_number_bytes()
192 }
193
194 #[cfg(feature = "json")]
196 #[must_use]
197 #[inline(always)]
198 pub const fn max_json_payload_bytes(&self) -> Option<usize> {
199 self.json.max_payload_bytes()
200 }
201}
202
203impl RedactionLimitsBuilder {
204 pub fn max_input_bytes(&mut self, maximum: usize) -> &mut Self {
206 self.max_input_bytes = maximum;
207 self
208 }
209
210 pub fn max_output_bytes(&mut self, maximum: usize) -> &mut Self {
212 self.max_output_bytes = maximum;
213 self
214 }
215
216 pub fn max_depth(&mut self, maximum: usize) -> &mut Self {
218 self.domain = self.domain.into_builder().max_depth(maximum).build();
219 self
220 }
221
222 pub fn max_nodes(&mut self, maximum: usize) -> &mut Self {
224 self.domain = self.domain.into_builder().max_nodes(maximum).build();
225 self
226 }
227
228 pub fn max_collection_items(&mut self, maximum: usize) -> &mut Self {
230 self.domain = self
231 .domain
232 .into_builder()
233 .max_sequence_items(maximum)
234 .max_map_entries(maximum)
235 .build();
236 self
237 }
238
239 pub fn max_key_bytes(&mut self, maximum: usize) -> &mut Self {
241 self.domain = self.domain.into_builder().max_key_bytes(maximum).build();
242 self
243 }
244
245 #[cfg(feature = "json")]
247 pub fn max_json_depth(&mut self, maximum: usize) -> &mut Self {
248 self.json = self.json.into_builder().max_depth(maximum).build();
249 self
250 }
251
252 #[cfg(feature = "json")]
254 pub fn max_json_nodes(&mut self, maximum: usize) -> &mut Self {
255 self.json = self.json.into_builder().max_nodes(maximum).build();
256 self
257 }
258
259 #[cfg(feature = "json")]
261 pub fn max_json_collection_items(&mut self, maximum: usize) -> &mut Self {
262 self.json = self
263 .json
264 .into_builder()
265 .max_sequence_items(maximum)
266 .max_map_entries(maximum)
267 .build();
268 self
269 }
270
271 #[cfg(feature = "json")]
273 pub fn max_json_key_bytes(&mut self, maximum: usize) -> &mut Self {
274 self.json = self.json.into_builder().max_key_bytes(maximum).build();
275 self
276 }
277
278 #[cfg(feature = "json")]
280 pub fn max_json_string_bytes(&mut self, maximum: usize) -> &mut Self {
281 self.json = self.json.into_builder().max_string_bytes(maximum).build();
282 self
283 }
284
285 #[cfg(feature = "json")]
287 pub fn max_json_number_bytes(&mut self, maximum: usize) -> &mut Self {
288 self.json = self.json.into_builder().max_number_bytes(maximum).build();
289 self
290 }
291
292 #[cfg(feature = "json")]
294 pub fn max_json_payload_bytes(&mut self, maximum: usize) -> &mut Self {
295 self.json = self.json.into_builder().max_payload_bytes(maximum).build();
296 self
297 }
298
299 #[must_use]
301 pub fn build(self) -> RedactionLimits {
302 RedactionLimits {
303 max_input_bytes: self.max_input_bytes,
304 max_output_bytes: self.max_output_bytes,
305 domain: self.domain,
306 #[cfg(feature = "json")]
307 json: self.json,
308 }
309 }
310}
311
312impl Default for RedactionLimitsBuilder {
313 fn default() -> Self {
315 Self {
316 max_input_bytes: 64 * 1024,
317 max_output_bytes: 16 * 1024,
318 domain: StructureLimits::builder()
319 .max_depth(32)
320 .max_nodes(1_024)
321 .max_sequence_items(256)
322 .max_map_entries(256)
323 .max_key_bytes(256)
324 .build(),
325 #[cfg(feature = "json")]
326 json: JsonValueLimits::default(),
327 }
328 }
329}
330
331impl Default for RedactionLimits {
332 fn default() -> Self {
334 Self::builder().build()
335 }
336}