qubit_json/decode/json_validated_decode_options.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//! Validated JSON decode configuration.
9
10use super::JsonDecodeNumberModel;
11use super::JsonRootKind;
12use super::JsonValidatedAdmissionPolicy;
13use super::JsonValidatedDecodeOptionsBuilder;
14
15/// Generic structural and source-token limits for validated decoding.
16///
17/// By default, no additional limits are imposed and the number model is
18/// `Integer64`. A limit set to `Some(0)` is a real zero-item/zero-byte limit;
19/// `None` means that the corresponding additional limit is disabled. Value
20/// nodes and object-key nodes both count toward the node limit. String limits
21/// count the source spelling inside each token, excluding quotes and
22/// including escape bytes such as the six bytes in `\u0061`.
23///
24/// # Examples
25///
26/// ```
27/// use qubit_json::decode::{JsonDecoder, JsonNumberPolicy, JsonValidatedDecodeOptions};
28///
29/// let options = JsonValidatedDecodeOptions::builder()
30/// .max_value_and_key_nodes(3)
31/// .max_encoded_string_bytes(8)
32/// .build();
33/// let value = JsonDecoder::unlimited().decode_unique_validated_str(
34/// r#"{"id":42}"#,
35/// &options,
36/// |_path, _token| Ok::<_, std::convert::Infallible>(JsonNumberPolicy::ExactSafeInteger),
37/// )?;
38/// assert_eq!(value.as_value()["id"].as_i64(), Some(42));
39/// # Ok::<(), Box<dyn std::error::Error>>(())
40/// ```
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct JsonValidatedDecodeOptions {
43 /// Required root kind, when the caller configured one.
44 pub(super) root_kind: Option<JsonRootKind>,
45 /// Token admission order for validated decoding.
46 pub(super) admission_policy: JsonValidatedAdmissionPolicy,
47 /// Representation model used for numbers selected for preservation.
48 pub(super) number_model: JsonDecodeNumberModel,
49 /// Optional combined count for value nodes and object-key nodes.
50 pub(super) max_value_and_key_nodes: Option<usize>,
51 /// Optional maximum source bytes inside each string token.
52 pub(super) max_encoded_string_bytes: Option<usize>,
53}
54
55impl JsonValidatedDecodeOptions {
56 /// Creates a builder with no extra limits and the `Integer64` model.
57 ///
58 /// # Returns
59 ///
60 /// A builder whose optional root kind and additional limits are unset.
61 #[must_use]
62 #[inline]
63 pub fn builder() -> JsonValidatedDecodeOptionsBuilder {
64 JsonValidatedDecodeOptionsBuilder::default()
65 }
66 /// Returns the optional required root kind. `None` accepts any root kind.
67 ///
68 /// # Returns
69 ///
70 /// The required root kind, or `None` when no root-kind restriction applies.
71 #[must_use]
72 #[inline]
73 pub const fn root_kind(&self) -> Option<JsonRootKind> {
74 self.root_kind
75 }
76 /// Returns the token admission order used by validated decoding.
77 ///
78 /// # Returns
79 ///
80 /// The configured policy. The default is
81 /// [`JsonValidatedAdmissionPolicy::Immediate`].
82 #[must_use]
83 #[inline]
84 pub const fn admission_policy(&self) -> JsonValidatedAdmissionPolicy {
85 self.admission_policy
86 }
87 /// Returns the selected number model.
88 ///
89 /// # Returns
90 ///
91 /// The number representation model used for preserved numbers.
92 #[must_use]
93 #[inline]
94 pub const fn number_model(&self) -> JsonDecodeNumberModel {
95 self.number_model
96 }
97 /// Returns the optional per-document value-and-key node limit. `None`
98 /// disables this additional limit; `Some(0)` permits no nodes.
99 ///
100 /// # Returns
101 ///
102 /// The configured combined node limit, or `None` when it is disabled.
103 #[must_use]
104 #[inline]
105 pub const fn max_value_and_key_nodes(&self) -> Option<usize> {
106 self.max_value_and_key_nodes
107 }
108 /// Returns the optional per-token source-string byte limit. It excludes
109 /// the quotes and includes escape spelling bytes. `None` disables this
110 /// additional limit; `Some(0)` permits only empty string token contents.
111 ///
112 /// # Returns
113 ///
114 /// The configured per-token source-byte limit, or `None` when disabled.
115 #[must_use]
116 #[inline]
117 pub const fn max_encoded_string_bytes(&self) -> Option<usize> {
118 self.max_encoded_string_bytes
119 }
120}