1use smallvec::SmallVec;
39use std::{fmt, str::FromStr};
40
41pub use locspan;
42
43#[cfg(feature = "canonicalize")]
44pub use ryu_js;
45
46pub mod array;
47pub mod code_map;
48mod convert;
49pub mod kind;
50pub mod lexical;
51mod macros;
52pub mod number;
53pub mod object;
54pub mod parse;
55pub mod print;
56pub mod string;
57pub mod tracing;
58pub mod visitor;
59
60pub use array::{JsonArray, JsonArrayBuf};
61pub use code_map::JsonCodeMap;
62pub use kind::{JsonKind, JsonKindSet};
63use lexical::{JsonBorrowLexical, JsonLexicalEq, JsonLexicalPartialEq};
64pub use number::{InvalidJsonNumber, JsonNumber, JsonNumberBuf};
65pub use object::JsonObject;
66pub use parse::JsonParse;
67pub use print::JsonPrint;
68pub use string::JsonString;
69
70#[cfg(feature = "serde")]
71pub mod serde;
72
73#[cfg(feature = "serde")]
74pub use serde::{from_slice, from_str, from_value, to_value};
75
76use crate::array::JsonArrayExt;
77
78#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
138pub enum JsonValue {
139 Null,
141
142 Boolean(bool),
144
145 Number(JsonNumberBuf),
147
148 String(JsonString),
150
151 Array(JsonArrayBuf),
153
154 Object(JsonObject),
156}
157
158impl JsonValue {
159 pub fn get_fragment(&self, index: usize) -> Result<JsonFragment<'_>, usize> {
160 if index == 0 {
161 Ok(JsonFragment::Value(self))
162 } else {
163 match self {
164 Self::Array(a) => a.get_fragment(index - 1),
165 Self::Object(o) => o.get_fragment(index - 1),
166 _ => Err(index - 1),
167 }
168 }
169 }
170
171 #[inline]
172 pub fn kind(&self) -> JsonKind {
173 match self {
174 Self::Null => JsonKind::Null,
175 Self::Boolean(_) => JsonKind::Boolean,
176 Self::Number(_) => JsonKind::Number,
177 Self::String(_) => JsonKind::String,
178 Self::Array(_) => JsonKind::Array,
179 Self::Object(_) => JsonKind::Object,
180 }
181 }
182
183 #[inline]
184 pub fn is_kind(&self, kind: JsonKind) -> bool {
185 self.kind() == kind
186 }
187
188 #[inline]
189 pub fn is_null(&self) -> bool {
190 matches!(self, Self::Null)
191 }
192
193 #[inline]
194 pub fn is_boolean(&self) -> bool {
195 matches!(self, Self::Boolean(_))
196 }
197
198 #[inline]
199 pub fn is_number(&self) -> bool {
200 matches!(self, Self::Number(_))
201 }
202
203 #[inline]
204 pub fn is_string(&self) -> bool {
205 matches!(self, Self::String(_))
206 }
207
208 #[inline]
209 pub fn is_array(&self) -> bool {
210 matches!(self, Self::Array(_))
211 }
212
213 #[inline]
214 pub fn is_object(&self) -> bool {
215 matches!(self, Self::Object(_))
216 }
217
218 #[inline]
220 pub fn is_empty_array_or_object(&self) -> bool {
221 match self {
222 Self::Array(a) => a.is_empty(),
223 Self::Object(o) => o.is_empty(),
224 _ => false,
225 }
226 }
227
228 #[inline]
229 pub fn as_boolean(&self) -> Option<bool> {
230 match self {
231 Self::Boolean(b) => Some(*b),
232 _ => None,
233 }
234 }
235
236 #[inline]
237 pub fn as_boolean_mut(&mut self) -> Option<&mut bool> {
238 match self {
239 Self::Boolean(b) => Some(b),
240 _ => None,
241 }
242 }
243
244 #[inline]
245 pub fn as_number(&self) -> Option<&JsonNumber> {
246 match self {
247 Self::Number(n) => Some(n),
248 _ => None,
249 }
250 }
251
252 #[inline]
253 pub fn as_number_mut(&mut self) -> Option<&mut JsonNumberBuf> {
254 match self {
255 Self::Number(n) => Some(n),
256 _ => None,
257 }
258 }
259
260 #[inline]
261 pub fn as_string(&self) -> Option<&str> {
262 match self {
263 Self::String(s) => Some(s),
264 _ => None,
265 }
266 }
267
268 #[inline]
270 pub fn as_str(&self) -> Option<&str> {
271 self.as_string()
272 }
273
274 #[inline]
275 pub fn as_string_mut(&mut self) -> Option<&mut JsonString> {
276 match self {
277 Self::String(s) => Some(s),
278 _ => None,
279 }
280 }
281
282 #[inline]
283 pub fn as_array(&self) -> Option<&[Self]> {
284 match self {
285 Self::Array(a) => Some(a),
286 _ => None,
287 }
288 }
289
290 #[inline]
291 pub fn as_array_mut(&mut self) -> Option<&mut JsonArrayBuf> {
292 match self {
293 Self::Array(a) => Some(a),
294 _ => None,
295 }
296 }
297
298 #[inline]
303 pub fn force_as_array(&self) -> &[Self] {
304 match self {
305 Self::Array(a) => a,
306 other => core::slice::from_ref(other),
307 }
308 }
309
310 #[inline]
311 pub fn as_object(&self) -> Option<&JsonObject> {
312 match self {
313 Self::Object(o) => Some(o),
314 _ => None,
315 }
316 }
317
318 #[inline]
319 pub fn as_object_mut(&mut self) -> Option<&mut JsonObject> {
320 match self {
321 Self::Object(o) => Some(o),
322 _ => None,
323 }
324 }
325
326 #[inline]
327 pub fn into_boolean(self) -> Option<bool> {
328 match self {
329 Self::Boolean(b) => Some(b),
330 _ => None,
331 }
332 }
333
334 #[inline]
335 pub fn into_number(self) -> Option<JsonNumberBuf> {
336 match self {
337 Self::Number(n) => Some(n),
338 _ => None,
339 }
340 }
341
342 #[inline]
343 pub fn into_string(self) -> Option<JsonString> {
344 match self {
345 Self::String(s) => Some(s),
346 _ => None,
347 }
348 }
349
350 #[inline]
351 pub fn into_array(self) -> Option<JsonArrayBuf> {
352 match self {
353 Self::Array(a) => Some(a),
354 _ => None,
355 }
356 }
357
358 #[inline]
359 pub fn into_object(self) -> Option<JsonObject> {
360 match self {
361 Self::Object(o) => Some(o),
362 _ => None,
363 }
364 }
365
366 pub fn traverse(&self) -> Traverse<'_> {
367 let mut stack = SmallVec::new();
368 stack.push(JsonFragment::Value(self));
369 Traverse { offset: 0, stack }
370 }
371
372 pub fn count(&self, mut f: impl FnMut(usize, JsonFragment) -> bool) -> usize {
374 self.traverse().filter(|(i, q)| f(*i, *q)).count()
375 }
376
377 pub fn volume(&self) -> usize {
384 self.traverse().filter(|(_, f)| f.is_value()).count()
385 }
386
387 #[inline(always)]
389 pub fn take(&mut self) -> Self {
390 let mut result = Self::Null;
391 std::mem::swap(&mut result, self);
392 result
393 }
394
395 #[cfg(feature = "canonicalize")]
400 pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
401 match self {
402 Self::Number(n) => n.canonicalize_with(buffer),
403 Self::Array(a) => {
404 for item in a {
405 item.canonicalize_with(buffer)
406 }
407 }
408 Self::Object(o) => o.canonicalize_with(buffer),
409 _ => (),
410 }
411 }
412
413 #[cfg(feature = "canonicalize")]
416 pub fn canonicalize(&mut self) {
417 let mut buffer = ryu_js::Buffer::new();
418 self.canonicalize_with(&mut buffer)
419 }
420
421 #[cfg(feature = "canonicalize")]
424 pub fn canonicalized(&self) -> Self {
425 let mut result = self.clone();
426 result.canonicalize();
427 result
428 }
429}
430
431impl JsonBorrowLexical for JsonValue {}
432
433impl JsonLexicalPartialEq for JsonValue {
434 fn lexical_eq(&self, other: &Self) -> bool {
435 match (self, other) {
436 (Self::Null, Self::Null) => true,
437 (Self::Boolean(a), Self::Boolean(b)) => a == b,
438 (Self::Number(a), Self::Number(b)) => a == b,
439 (Self::String(a), Self::String(b)) => a == b,
440 (Self::Array(a), Self::Array(b)) => a.lexical_eq(b),
441 (Self::Object(a), Self::Object(b)) => a.lexical_eq(b),
442 _ => false,
443 }
444 }
445}
446
447impl JsonLexicalEq for JsonValue {}
448
449impl fmt::Display for JsonValue {
450 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
451 self.compact_print().fmt(f)
452 }
453}
454
455impl From<JsonValue> for ::std::string::String {
456 fn from(value: JsonValue) -> Self {
457 value.to_string()
458 }
459}
460
461impl From<bool> for JsonValue {
462 fn from(b: bool) -> Self {
463 Self::Boolean(b)
464 }
465}
466
467impl From<JsonNumberBuf> for JsonValue {
468 fn from(n: JsonNumberBuf) -> Self {
469 Self::Number(n)
470 }
471}
472
473impl<'n> From<&'n JsonNumber> for JsonValue {
474 fn from(n: &'n JsonNumber) -> Self {
475 Self::Number(unsafe { JsonNumberBuf::new_unchecked(n.as_bytes().into()) })
476 }
477}
478
479impl From<JsonString> for JsonValue {
480 fn from(s: JsonString) -> Self {
481 Self::String(s)
482 }
483}
484
485impl From<::std::string::String> for JsonValue {
486 fn from(s: ::std::string::String) -> Self {
487 Self::String(s.into())
488 }
489}
490
491impl<'s> From<&'s str> for JsonValue {
492 fn from(s: &'s str) -> Self {
493 Self::String(s.into())
494 }
495}
496
497impl From<JsonArrayBuf> for JsonValue {
498 fn from(a: JsonArrayBuf) -> Self {
499 Self::Array(a)
500 }
501}
502
503impl From<JsonObject> for JsonValue {
504 fn from(o: JsonObject) -> Self {
505 Self::Object(o)
506 }
507}
508
509impl FromStr for JsonValue {
510 type Err = parse::JsonParseError;
511
512 fn from_str(s: &str) -> Result<Self, Self::Err> {
513 Ok(Self::parse_str(s)?.0)
514 }
515}
516
517macro_rules! from_integer {
518 ($($ty:ident),*) => {
519 $(
520 impl From<$ty> for JsonValue {
521 fn from(n: $ty) -> Self {
522 JsonValue::Number(n.into())
523 }
524 }
525 )*
526 };
527}
528
529from_integer! {
530 u8,
531 u16,
532 u32,
533 u64,
534 i8,
535 i16,
536 i32,
537 i64
538}
539
540macro_rules! try_from_float {
541 ($($ty:ident),*) => {
542 $(
543 impl TryFrom<$ty> for JsonValue {
544 type Error = number::TryFromFloatError;
545
546 fn try_from(n: $ty) -> Result<Self, Self::Error> {
547 Ok(JsonValue::Number(n.try_into()?))
548 }
549 }
550 )*
551 };
552}
553
554try_from_float! {
555 f32,
556 f64
557}
558
559pub enum JsonFragment<'a> {
560 Value(&'a JsonValue),
561 Entry(object::EntryRef<'a>),
562 Key(&'a object::Key),
563}
564
565impl<'a> JsonFragment<'a> {
566 pub fn is_entry(&self) -> bool {
567 matches!(self, Self::Entry(_))
568 }
569
570 pub fn is_key(&self) -> bool {
571 matches!(self, Self::Key(_))
572 }
573
574 pub fn is_value(&self) -> bool {
575 matches!(self, Self::Value(_))
576 }
577
578 pub fn is_null(&self) -> bool {
579 matches!(self, Self::Value(JsonValue::Null))
580 }
581
582 pub fn is_number(&self) -> bool {
583 matches!(self, Self::Value(JsonValue::Number(_)))
584 }
585
586 pub fn is_string(&self) -> bool {
587 matches!(self, Self::Value(JsonValue::String(_)))
588 }
589
590 pub fn is_array(&self) -> bool {
591 matches!(self, Self::Value(JsonValue::Array(_)))
592 }
593
594 pub fn is_object(&self) -> bool {
595 matches!(self, Self::Value(JsonValue::Object(_)))
596 }
597
598 pub fn strip(self) -> JsonFragment<'a> {
599 match self {
600 Self::Value(v) => JsonFragment::Value(v),
601 Self::Entry(e) => JsonFragment::Entry(e),
602 Self::Key(k) => JsonFragment::Key(k),
603 }
604 }
605}
606
607impl<'a> Clone for JsonFragment<'a> {
608 fn clone(&self) -> Self {
609 *self
610 }
611}
612
613impl<'a> Copy for JsonFragment<'a> {}
614
615impl<'a> JsonFragment<'a> {
616 pub fn sub_fragments(&self) -> JsonFragments<'a> {
617 match self {
618 Self::Value(JsonValue::Array(a)) => JsonFragments::Array(a.iter()),
619 Self::Value(JsonValue::Object(o)) => JsonFragments::Object(o.iter()),
620 Self::Entry((key, value)) => JsonFragments::Entry(Some(key), Some(value)),
621 _ => JsonFragments::None,
622 }
623 }
624}
625
626pub enum JsonFragments<'a> {
627 None,
628 Array(core::slice::Iter<'a, JsonValue>),
629 Object(object::Iter<'a>),
630 Entry(Option<&'a object::Key>, Option<&'a JsonValue>),
631}
632
633impl<'a> Iterator for JsonFragments<'a> {
634 type Item = JsonFragment<'a>;
635
636 fn next(&mut self) -> Option<Self::Item> {
637 match self {
638 Self::None => None,
639 Self::Array(a) => a.next().map(JsonFragment::Value),
640 Self::Object(e) => e.next().map(JsonFragment::Entry),
641 Self::Entry(k, v) => k
642 .take()
643 .map(JsonFragment::Key)
644 .or_else(|| v.take().map(JsonFragment::Value)),
645 }
646 }
647}
648
649impl<'a> DoubleEndedIterator for JsonFragments<'a> {
650 fn next_back(&mut self) -> Option<Self::Item> {
651 match self {
652 Self::None => None,
653 Self::Array(a) => a.next_back().map(JsonFragment::Value),
654 Self::Object(e) => e.next_back().map(JsonFragment::Entry),
655 Self::Entry(k, v) => v
656 .take()
657 .map(JsonFragment::Value)
658 .or_else(|| k.take().map(JsonFragment::Key)),
659 }
660 }
661}
662
663pub struct Traverse<'a> {
664 offset: usize,
665 stack: SmallVec<[JsonFragment<'a>; 8]>,
666}
667
668impl<'a> Iterator for Traverse<'a> {
669 type Item = (usize, JsonFragment<'a>);
670
671 fn next(&mut self) -> Option<Self::Item> {
672 match self.stack.pop() {
673 Some(v) => {
674 self.stack.extend(v.sub_fragments().rev());
675 let i = self.offset;
676 self.offset += 1;
677 Some((i, v))
678 }
679 None => None,
680 }
681 }
682}
683
684#[cfg(test)]
685mod tests {
686 #[cfg(feature = "canonicalize")]
687 #[test]
688 fn canonicalize_01() {
689 use super::*;
690 let mut value: JsonValue = json!({
691 "b": 0.00000000001,
692 "c": {
693 "foo": true,
694 "bar": false
695 },
696 "a": [ "foo", "bar" ]
697 });
698
699 value.canonicalize();
700
701 assert_eq!(
702 value.compact_print().to_string(),
703 "{\"a\":[\"foo\",\"bar\"],\"b\":1e-11,\"c\":{\"bar\":false,\"foo\":true}}"
704 )
705 }
706
707 #[cfg(feature = "canonicalize")]
708 #[test]
709 fn canonicalize_02() {
710 use super::*;
711 let (mut value, _) = JsonValue::parse_str(
712 "{
713 \"numbers\": [333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001],
714 \"string\": \"\\u20ac$\\u000F\\u000aA'\\u0042\\u0022\\u005c\\\\\\\"\\/\",
715 \"literals\": [null, true, false]
716 }",
717 )
718 .unwrap();
719
720 value.canonicalize();
721
722 assert_eq!(
723 value.compact_print().to_string(),
724 "{\"literals\":[null,true,false],\"numbers\":[333333333.3333333,1e+30,4.5,0.002,1e-27],\"string\":\"€$\\u000f\\nA'B\\\"\\\\\\\\\\\"/\"}"
725 )
726 }
727}