Skip to main content

qubit_json/decode/
json_validated_decode_options_builder.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//! Builder for validated JSON decode configuration.
9
10use super::JsonDecodeNumberModel;
11use super::JsonRootKind;
12use super::JsonValidatedAdmissionPolicy;
13use super::JsonValidatedDecodeOptions;
14
15/// Builds [`JsonValidatedDecodeOptions`].
16///
17/// Unset optional settings impose no additional limit. A configured zero is a
18/// valid bound and permits zero counted nodes or zero source bytes.
19///
20/// # Examples
21///
22/// ```
23/// use qubit_json::decode::{JsonDecoder, JsonNumberPolicy, JsonValidatedDecodeOptions};
24///
25/// let options = JsonValidatedDecodeOptions::builder()
26///     .max_value_and_key_nodes(3)
27///     .max_encoded_string_bytes(8)
28///     .build();
29/// let value = JsonDecoder::unlimited().decode_unique_validated_str(
30///     r#"{"id":42}"#,
31///     &options,
32///     |_path, _token| Ok::<_, std::convert::Infallible>(JsonNumberPolicy::ExactSafeInteger),
33/// )?;
34/// assert_eq!(value.as_value()["id"].as_i64(), Some(42));
35/// # Ok::<(), Box<dyn std::error::Error>>(())
36/// ```
37#[derive(Debug, Clone, Default)]
38pub struct JsonValidatedDecodeOptionsBuilder {
39    /// Required root kind, when configured.
40    root_kind: Option<JsonRootKind>,
41    /// Token admission order for validated decoding.
42    admission_policy: JsonValidatedAdmissionPolicy,
43    /// Representation model used for preserved numbers.
44    number_model: JsonDecodeNumberModel,
45    /// Optional combined value-node and object-key-node limit.
46    max_value_and_key_nodes: Option<usize>,
47    /// Optional per-string-token source-byte limit.
48    max_encoded_string_bytes: Option<usize>,
49}
50
51impl JsonValidatedDecodeOptionsBuilder {
52    /// Selects the token admission order for validated decoding.
53    ///
54    /// # Parameters
55    ///
56    /// * `policy` - The admission order to use.
57    ///
58    /// # Returns
59    ///
60    /// The builder configured with the selected admission policy.
61    pub fn admission_policy(mut self, policy: JsonValidatedAdmissionPolicy) -> Self {
62        self.admission_policy = policy;
63        self
64    }
65    /// Requires a particular root kind.
66    ///
67    /// # Parameters
68    ///
69    /// * `kind` - Root kind required for a successfully decoded document.
70    ///
71    /// # Returns
72    ///
73    /// The builder configured with the required root kind.
74    pub fn root_kind(mut self, kind: JsonRootKind) -> Self {
75        self.root_kind = Some(kind);
76        self
77    }
78    /// Selects the number representation model.
79    ///
80    /// # Parameters
81    ///
82    /// * `model` - Number representation model used when numbers are preserved.
83    ///
84    /// # Returns
85    ///
86    /// The builder configured with the selected number model.
87    pub fn number_model(mut self, model: JsonDecodeNumberModel) -> Self {
88        self.number_model = model;
89        self
90    }
91    /// Limits value entries and decoded object-key entries per document.
92    ///
93    /// Every JSON value counts once, and every object key also counts once.
94    /// Zero is a valid limit and permits no counted entries.
95    ///
96    /// # Parameters
97    ///
98    /// * `maximum` - Maximum combined value and object-key node count.
99    ///
100    /// # Returns
101    ///
102    /// The builder with this per-document limit configured.
103    pub fn max_value_and_key_nodes(mut self, maximum: usize) -> Self {
104        self.max_value_and_key_nodes = Some(maximum);
105        self
106    }
107    /// Limits the source bytes inside each string token, excluding quotes.
108    /// Escape spelling is counted as it appears in the source, so `\u0061`
109    /// consumes six bytes. Zero permits only empty string token contents.
110    ///
111    /// # Parameters
112    ///
113    /// * `maximum` - Maximum number of source bytes inside each string token.
114    ///
115    /// # Returns
116    ///
117    /// The builder with this per-token limit configured.
118    pub fn max_encoded_string_bytes(mut self, maximum: usize) -> Self {
119        self.max_encoded_string_bytes = Some(maximum);
120        self
121    }
122    /// Builds the configured options.
123    ///
124    /// # Returns
125    ///
126    /// The options snapshot containing all configured settings.
127    pub fn build(self) -> JsonValidatedDecodeOptions {
128        JsonValidatedDecodeOptions {
129            root_kind: self.root_kind,
130            admission_policy: self.admission_policy,
131            number_model: self.number_model,
132            max_value_and_key_nodes: self.max_value_and_key_nodes,
133            max_encoded_string_bytes: self.max_encoded_string_bytes,
134        }
135    }
136}