1use std::borrow::Cow;
2use std::sync::Arc;
3
4#[cfg(feature = "num-bigint")]
5use num_bigint::BigInt;
6use smallvec::SmallVec;
7
8use crate::errors::{json_error, JsonError, JsonResult, DEFAULT_RECURSION_LIMIT};
9use crate::lazy_index_map::LazyIndexMap;
10use crate::number_decoder::{NumberAny, NumberInt, NumberRange};
11use crate::parse::{Parser, Peek};
12use crate::string_decoder::{StringDecoder, StringDecoderRange, StringOutput, Tape};
13
14#[derive(Clone, Debug, PartialEq)]
16pub enum JsonValue<'s> {
17 Null,
18 Bool(bool),
19 Int(i64),
20 #[cfg(feature = "num-bigint")]
21 BigInt(BigInt),
22 Float(f64),
23 Str(Cow<'s, str>),
24 Array(JsonArray<'s>),
25 Object(JsonObject<'s>),
26}
27
28pub type JsonArray<'s> = Arc<SmallVec<[JsonValue<'s>; 8]>>;
29pub type JsonObject<'s> = Arc<LazyIndexMap<Cow<'s, str>, JsonValue<'s>>>;
30
31#[cfg(feature = "python")]
32impl pyo3::ToPyObject for JsonValue<'_> {
33 fn to_object(&self, py: pyo3::Python<'_>) -> pyo3::PyObject {
34 use pyo3::prelude::*;
35 match self {
36 Self::Null => py.None().to_object(py),
37 Self::Bool(b) => b.to_object(py),
38 Self::Int(i) => i.to_object(py),
39 #[cfg(feature = "num-bigint")]
40 Self::BigInt(b) => b.to_object(py),
41 Self::Float(f) => f.to_object(py),
42 Self::Str(s) => s.to_object(py),
43 Self::Array(v) => pyo3::types::PyList::new_bound(py, v.iter().map(|v| v.to_object(py))).to_object(py),
44 Self::Object(o) => {
45 let dict = pyo3::types::PyDict::new_bound(py);
46 for (k, v) in o.iter() {
47 dict.set_item(k, v.to_object(py)).unwrap();
48 }
49 dict.to_object(py)
50 }
51 }
52 }
53}
54
55impl<'j> JsonValue<'j> {
56 pub fn parse(data: &'j [u8], allow_inf_nan: bool) -> Result<Self, JsonError> {
59 let mut parser = Parser::new(data);
60
61 let mut tape = Tape::default();
62 let peek = parser.peek()?;
63 let v = take_value_borrowed(peek, &mut parser, &mut tape, DEFAULT_RECURSION_LIMIT, allow_inf_nan)?;
64 parser.finish()?;
65 Ok(v)
66 }
67
68 pub fn into_static(self) -> JsonValue<'static> {
70 value_static(self)
71 }
72
73 pub fn to_static(&self) -> JsonValue<'static> {
75 value_static(self.clone())
76 }
77}
78
79fn value_static(v: JsonValue<'_>) -> JsonValue<'static> {
80 match v {
81 JsonValue::Null => JsonValue::Null,
82 JsonValue::Bool(b) => JsonValue::Bool(b),
83 JsonValue::Int(i) => JsonValue::Int(i),
84 #[cfg(feature = "num-bigint")]
85 JsonValue::BigInt(b) => JsonValue::BigInt(b),
86 JsonValue::Float(f) => JsonValue::Float(f),
87 JsonValue::Str(s) => JsonValue::Str(s.into_owned().into()),
88 JsonValue::Array(v) => JsonValue::Array(Arc::new(v.iter().map(JsonValue::to_static).collect::<SmallVec<_>>())),
89 JsonValue::Object(o) => JsonValue::Object(Arc::new(o.to_static())),
90 }
91}
92
93impl JsonValue<'static> {
94 pub fn parse_owned(data: &[u8], allow_inf_nan: bool) -> Result<Self, JsonError> {
96 let mut parser = Parser::new(data);
97
98 let mut tape = Tape::default();
99 let peek = parser.peek()?;
100 let v = take_value_owned(peek, &mut parser, &mut tape, DEFAULT_RECURSION_LIMIT, allow_inf_nan)?;
101 parser.finish()?;
102 Ok(v)
103 }
104}
105
106pub(crate) fn take_value_borrowed<'j>(
107 peek: Peek,
108 parser: &mut Parser<'j>,
109 tape: &mut Tape,
110 recursion_limit: u8,
111 allow_inf_nan: bool,
112) -> JsonResult<JsonValue<'j>> {
113 take_value(
114 peek,
115 parser,
116 tape,
117 recursion_limit,
118 allow_inf_nan,
119 &|s: StringOutput<'_, 'j>| s.into(),
120 )
121}
122
123pub(crate) fn take_value_owned<'j>(
124 peek: Peek,
125 parser: &mut Parser<'j>,
126 tape: &mut Tape,
127 recursion_limit: u8,
128 allow_inf_nan: bool,
129) -> JsonResult<JsonValue<'static>> {
130 take_value(
131 peek,
132 parser,
133 tape,
134 recursion_limit,
135 allow_inf_nan,
136 &|s: StringOutput<'_, 'j>| Into::<String>::into(s).into(),
137 )
138}
139
140fn take_value<'j, 's>(
141 peek: Peek,
142 parser: &mut Parser<'j>,
143 tape: &mut Tape,
144 recursion_limit: u8,
145 allow_inf_nan: bool,
146 create_cow: &impl Fn(StringOutput<'_, 'j>) -> Cow<'s, str>,
147) -> JsonResult<JsonValue<'s>> {
148 match peek {
149 Peek::True => {
150 parser.consume_true()?;
151 Ok(JsonValue::Bool(true))
152 }
153 Peek::False => {
154 parser.consume_false()?;
155 Ok(JsonValue::Bool(false))
156 }
157 Peek::Null => {
158 parser.consume_null()?;
159 Ok(JsonValue::Null)
160 }
161 Peek::String => {
162 let s: StringOutput<'_, 'j> = parser.consume_string::<StringDecoder>(tape, false)?;
163 Ok(JsonValue::Str(create_cow(s)))
164 }
165 Peek::Array => {
166 let array = Arc::new(SmallVec::new());
168 if let Some(peek_first) = parser.array_first()? {
169 take_value_recursive(
170 peek_first,
171 RecursedValue::Array(array),
172 parser,
173 tape,
174 recursion_limit,
175 allow_inf_nan,
176 create_cow,
177 )
178 } else {
179 Ok(JsonValue::Array(array))
180 }
181 }
182 Peek::Object => {
183 let object = Arc::new(LazyIndexMap::new());
185 if let Some(first_key) = parser.object_first::<StringDecoder>(tape)? {
186 let first_key = create_cow(first_key);
187 take_value_recursive(
188 parser.peek()?,
189 RecursedValue::Object {
190 partial: object,
191 next_key: first_key,
192 },
193 parser,
194 tape,
195 recursion_limit,
196 allow_inf_nan,
197 create_cow,
198 )
199 } else {
200 Ok(JsonValue::Object(object))
201 }
202 }
203 _ => {
204 let n = parser.consume_number::<NumberAny>(peek.into_inner(), allow_inf_nan);
205 match n {
206 Ok(NumberAny::Int(NumberInt::Int(int))) => Ok(JsonValue::Int(int)),
207 #[cfg(feature = "num-bigint")]
208 Ok(NumberAny::Int(NumberInt::BigInt(big_int))) => Ok(JsonValue::BigInt(big_int)),
209 Ok(NumberAny::Float(float)) => Ok(JsonValue::Float(float)),
210 Err(e) => {
211 if !peek.is_num() {
212 Err(json_error!(ExpectedSomeValue, parser.index))
213 } else {
214 Err(e)
215 }
216 }
217 }
218 }
219 }
220}
221
222enum RecursedValue<'s> {
223 Array(JsonArray<'s>),
224 Object {
225 partial: JsonObject<'s>,
226 next_key: Cow<'s, str>,
227 },
228}
229
230#[inline(never)] #[allow(clippy::too_many_lines)] fn take_value_recursive<'j, 's>(
233 mut peek: Peek,
234 mut current_recursion: RecursedValue<'s>,
235 parser: &mut Parser<'j>,
236 tape: &mut Tape,
237 recursion_limit: u8,
238 allow_inf_nan: bool,
239 create_cow: &impl Fn(StringOutput<'_, 'j>) -> Cow<'s, str>,
240) -> JsonResult<JsonValue<'s>> {
241 let recursion_limit: usize = recursion_limit.into();
242
243 let mut recursion_stack: SmallVec<[RecursedValue; 8]> = SmallVec::new();
244
245 macro_rules! push_recursion {
246 ($next_peek:expr, $value:expr) => {
247 peek = $next_peek;
248 recursion_stack.push(std::mem::replace(&mut current_recursion, $value));
249 if recursion_stack.len() >= recursion_limit {
250 return Err(json_error!(RecursionLimitExceeded, parser.index));
251 }
252 };
253 }
254
255 'recursion: loop {
256 let mut value = match &mut current_recursion {
257 RecursedValue::Array(array) => {
258 let array = Arc::get_mut(array).expect("sole writer");
259 loop {
260 let value = match peek {
261 Peek::True => {
262 parser.consume_true()?;
263 JsonValue::Bool(true)
264 }
265 Peek::False => {
266 parser.consume_false()?;
267 JsonValue::Bool(false)
268 }
269 Peek::Null => {
270 parser.consume_null()?;
271 JsonValue::Null
272 }
273 Peek::String => {
274 let s = parser.consume_string::<StringDecoder>(tape, false)?;
275 JsonValue::Str(create_cow(s))
276 }
277 Peek::Array => {
278 let array = Arc::new(SmallVec::new());
279 if let Some(next_peek) = parser.array_first()? {
280 push_recursion!(next_peek, RecursedValue::Array(array));
281 continue 'recursion;
283 }
284 JsonValue::Array(array)
285 }
286 Peek::Object => {
287 let object = Arc::new(LazyIndexMap::new());
288 if let Some(next_key) = parser.object_first::<StringDecoder>(tape)? {
289 push_recursion!(
290 parser.peek()?,
291 RecursedValue::Object {
292 partial: object,
293 next_key: create_cow(next_key)
294 }
295 );
296 continue 'recursion;
297 }
298 JsonValue::Object(object)
299 }
300 _ => {
301 let n = parser
302 .consume_number::<NumberAny>(peek.into_inner(), allow_inf_nan)
303 .map_err(|e| {
304 if !peek.is_num() {
305 json_error!(ExpectedSomeValue, parser.index)
306 } else {
307 e
308 }
309 })?;
310 match n {
311 NumberAny::Int(NumberInt::Int(int)) => JsonValue::Int(int),
312 NumberAny::Int(NumberInt::BigInt(big_int)) => JsonValue::BigInt(big_int),
313 NumberAny::Float(float) => JsonValue::Float(float),
314 }
315 }
316 };
317
318 if let Some(next_peek) = parser.array_step()? {
320 array.push(value);
321 peek = next_peek;
322 continue;
324 }
325
326 let RecursedValue::Array(mut array) = current_recursion else {
327 unreachable!("known to be in array recursion");
328 };
329
330 Arc::get_mut(&mut array).expect("sole writer to value").push(value);
331 break JsonValue::Array(array);
332 }
333 }
334 RecursedValue::Object { partial, next_key } => {
335 let partial = Arc::get_mut(partial).expect("sole writer");
336 loop {
337 let value = match peek {
338 Peek::True => {
339 parser.consume_true()?;
340 JsonValue::Bool(true)
341 }
342 Peek::False => {
343 parser.consume_false()?;
344 JsonValue::Bool(false)
345 }
346 Peek::Null => {
347 parser.consume_null()?;
348 JsonValue::Null
349 }
350 Peek::String => {
351 let s = parser.consume_string::<StringDecoder>(tape, false)?;
352 JsonValue::Str(create_cow(s))
353 }
354 Peek::Array => {
355 let array = Arc::new(SmallVec::new());
356 if let Some(next_peek) = parser.array_first()? {
357 push_recursion!(next_peek, RecursedValue::Array(array));
358 continue 'recursion;
360 }
361 JsonValue::Array(array)
362 }
363 Peek::Object => {
364 let object = Arc::new(LazyIndexMap::new());
365 if let Some(yet_another_key) = parser.object_first::<StringDecoder>(tape)? {
366 push_recursion!(
367 parser.peek()?,
368 RecursedValue::Object {
369 partial: object,
370 next_key: create_cow(yet_another_key)
371 }
372 );
373 continue 'recursion;
374 }
375 JsonValue::Object(object)
376 }
377 _ => {
378 let n = parser
379 .consume_number::<NumberAny>(peek.into_inner(), allow_inf_nan)
380 .map_err(|e| {
381 if !peek.is_num() {
382 json_error!(ExpectedSomeValue, parser.index)
383 } else {
384 e
385 }
386 })?;
387 match n {
388 NumberAny::Int(NumberInt::Int(int)) => JsonValue::Int(int),
389 NumberAny::Int(NumberInt::BigInt(big_int)) => JsonValue::BigInt(big_int),
390 NumberAny::Float(float) => JsonValue::Float(float),
391 }
392 }
393 };
394
395 if let Some(yet_another_key) = parser.object_step::<StringDecoder>(tape)?.map(create_cow) {
397 partial.insert(std::mem::replace(next_key, yet_another_key), value);
399 peek = parser.peek()?;
400 continue;
401 }
402
403 let RecursedValue::Object { mut partial, next_key } = current_recursion else {
404 unreachable!("known to be in object recursion");
405 };
406
407 Arc::get_mut(&mut partial).expect("sole writer").insert(next_key, value);
408 break JsonValue::Object(partial);
409 }
410 }
411 };
412
413 peek = loop {
416 if let Some(next_recursion) = recursion_stack.pop() {
417 current_recursion = next_recursion;
418 } else {
419 return Ok(value);
420 }
421
422 value = match current_recursion {
423 RecursedValue::Array(mut array) => {
424 Arc::get_mut(&mut array).expect("sole writer").push(value);
425 if let Some(next_peek) = parser.array_step()? {
426 current_recursion = RecursedValue::Array(array);
427 break next_peek;
428 }
429 JsonValue::Array(array)
430 }
431 RecursedValue::Object { mut partial, next_key } => {
432 Arc::get_mut(&mut partial).expect("sole writer").insert(next_key, value);
433 if let Some(next_key) = parser.object_step::<StringDecoder>(tape)?.map(create_cow) {
434 current_recursion = RecursedValue::Object { partial, next_key };
435 break parser.peek()?;
436 }
437 JsonValue::Object(partial)
438 }
439 }
440 };
441 }
442}
443
444pub(crate) fn take_value_skip(
447 peek: Peek,
448 parser: &mut Parser,
449 tape: &mut Tape,
450 recursion_limit: u8,
451 allow_inf_nan: bool,
452) -> JsonResult<()> {
453 match peek {
454 Peek::True => parser.consume_true(),
455 Peek::False => parser.consume_false(),
456 Peek::Null => parser.consume_null(),
457 Peek::String => parser.consume_string::<StringDecoderRange>(tape, false).map(drop),
458 Peek::Array => {
459 if let Some(next_peek) = parser.array_first()? {
460 take_value_skip_recursive(next_peek, ARRAY, parser, tape, recursion_limit, allow_inf_nan)
461 } else {
462 Ok(())
463 }
464 }
465 Peek::Object => {
466 if parser.object_first::<StringDecoderRange>(tape)?.is_some() {
467 take_value_skip_recursive(parser.peek()?, OBJECT, parser, tape, recursion_limit, allow_inf_nan)
468 } else {
469 Ok(())
470 }
471 }
472 _ => parser
473 .consume_number::<NumberRange>(peek.into_inner(), allow_inf_nan)
474 .map(drop)
475 .map_err(|e| {
476 if !peek.is_num() {
477 json_error!(ExpectedSomeValue, parser.index)
478 } else {
479 e
480 }
481 }),
482 }
483}
484
485const ARRAY: bool = false;
486const OBJECT: bool = true;
487
488#[inline(never)] fn take_value_skip_recursive(
490 mut peek: Peek,
491 mut current_recursion: bool,
492 parser: &mut Parser,
493 tape: &mut Tape,
494 recursion_limit: u8,
495 allow_inf_nan: bool,
496) -> JsonResult<()> {
497 let mut recursion_stack = bitvec::bitarr![0; 256];
498 let recursion_limit: usize = recursion_limit.into();
499 let mut current_recursion_depth = 0;
500
501 macro_rules! push_recursion {
502 ($next_peek:expr, $value:expr) => {
503 peek = $next_peek;
504 recursion_stack.set(
505 current_recursion_depth,
506 std::mem::replace(&mut current_recursion, $value),
507 );
508 current_recursion_depth += 1;
509 if current_recursion_depth >= recursion_limit {
510 return Err(json_error!(RecursionLimitExceeded, parser.index));
511 }
512 };
513 }
514
515 loop {
516 match peek {
517 Peek::True => parser.consume_true()?,
518 Peek::False => parser.consume_false()?,
519 Peek::Null => parser.consume_null()?,
520 Peek::String => {
521 parser.consume_string::<StringDecoderRange>(tape, false)?;
522 }
523 Peek::Array => {
524 if let Some(next_peek) = parser.array_first()? {
525 push_recursion!(next_peek, ARRAY);
526 continue;
528 }
529 }
530 Peek::Object => {
531 if parser.object_first::<StringDecoderRange>(tape)?.is_some() {
532 push_recursion!(parser.peek()?, OBJECT);
533 continue;
535 }
536 }
537 _ => {
538 parser
539 .consume_number::<NumberRange>(peek.into_inner(), allow_inf_nan)
540 .map_err(|e| {
541 if !peek.is_num() {
542 json_error!(ExpectedSomeValue, parser.index)
543 } else {
544 e
545 }
546 })?;
547 }
548 };
549
550 peek = loop {
552 match current_recursion {
553 ARRAY => {
554 if let Some(next_peek) = parser.array_step()? {
555 break next_peek;
556 }
557 }
558 OBJECT => {
559 if parser.object_step::<StringDecoderRange>(tape)?.is_some() {
560 break parser.peek()?;
561 }
562 }
563 }
564
565 current_recursion_depth = match current_recursion_depth.checked_sub(1) {
566 Some(r) => r,
567 None => return Ok(()),
569 };
570
571 current_recursion = recursion_stack[current_recursion_depth];
572 };
573 }
574}