1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// =============================================================================
// Copyright (c) 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Incremental accounting deserialization into a JSON value tree.
use Debug;
use ResourceQuantity;
use JsonValueTransaction;
use Deserializer;
use DeserializeSeed;
use Value;
use JsonValueVisitor;
/// Serde seed that constructs a [`Value`] while accounting decoded resources.
///
/// Unlike lexical JSON admission, this seed observes values after a Serde
/// deserializer has decoded them. For a number, it charges `NumberBytes` using
/// the compact display length of the constructed [`serde_json::Number`], not
/// the original token length. It cannot inspect original number lexemes or
/// enforce text-level integer and floating-point range rules. Use
/// `JsonDecoder` when decoding JSON text requires those guarantees. This seed
/// remains suitable for decoded-value budget enforcement inside a type's
/// ordinary [`serde::Deserialize`] implementation, where the original input
/// bytes are unavailable.
///
/// Duplicate object keys use last-key-wins behavior by default. Call
/// [`Self::reject_duplicate_keys`] to reject duplicates throughout the value;
/// container and key budget checks still take precedence, and a duplicate's
/// value is not requested from the deserializer.
///
/// This seed stages measurements incrementally in the caller's transaction; it
/// does not commit or roll back that transaction. Any deserialization failure
/// may leave partial staged charges, and non-budget errors do not necessarily
/// poison the transaction. Drop the entire transaction after an error and start
/// a new transaction before retrying. This also discards earlier work staged in
/// that transaction.
///
/// Successful seed deserialization consumes one value, not necessarily a
/// complete document. Complete the deserializer's end-of-input check and any
/// required application validation before committing. If either fails, drop the
/// transaction.
///
/// Do not pass this seed to [`crate::decode::JsonDecoder::decode_seed_str`] or
/// [`crate::decode::JsonDecoder::decode_seed_utf8`] or
/// [`crate::decode::JsonDecoder::decode_unique_seed_utf8`] when its transaction
/// and the decoder represent the same logical decoded-value budget.
/// `JsonDecoder` already accounts the complete value during lexical admission,
/// so the seed would charge that value a second time. In that pipeline, use a
/// seed that performs only domain deserialization and domain-specific checks.
///
/// # Type Parameters
///
/// * `'transaction` - Lifetime of the mutable accounting transaction borrow.
/// * `'budget` - Lifetime of the budget state owned by that transaction.
/// * `R` - Resource identity tracked by the value transaction.
/// * `Q` - Quantity representation used for resource accounting.
///
/// # Examples
///
/// ```
/// use qubit_budget::json::{JsonResource, JsonValueBudget, JsonValueLimits};
/// use qubit_json::value::AccountingJsonValueSeed;
/// use serde::de::DeserializeSeed;
///
/// let mut budget = JsonValueBudget::new(JsonValueLimits::<JsonResource, usize>::default());
/// let mut transaction = budget.transaction();
/// let mut deserializer = serde_json::Deserializer::from_str(r#"{"ok":true}"#);
/// let value = AccountingJsonValueSeed::new(&mut transaction)
/// .reject_duplicate_keys()
/// .deserialize(&mut deserializer)?;
/// deserializer.end()?;
/// assert_eq!(value["ok"], true);
/// transaction.commit()?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```