1mod modifiers;
6mod multipath;
7mod path;
8mod pretty;
9mod test;
10pub mod tools;
12mod util;
13mod valid;
14
15use path::*;
16use std::cmp::Ordering;
17use std::fmt;
18use util::{pmatch, tostr, unescape};
19pub use valid::valid;
20
21type InfoBits = u32;
22
23#[derive(Copy, Clone, Eq)]
25pub enum Kind {
26 Null,
27 False,
28 Number,
29 String,
30 True,
31 Array,
32 Object,
33}
34
35impl PartialOrd for Kind {
36 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
37 Some(self.cmp(other))
38 }
39}
40
41impl PartialEq for Kind {
42 fn eq(&self, other: &Self) -> bool {
43 self.cmp(&other) == Ordering::Equal
44 }
45}
46
47impl Ord for Kind {
48 fn cmp(&self, other: &Self) -> Ordering {
49 (*self as i32).cmp(&(*other as i32))
50 }
51}
52
53const INFO_NULL: InfoBits = 1 << 1;
55const INFO_FALSE: InfoBits = 1 << 2;
56const INFO_NUMBER: InfoBits = 1 << 3;
57const INFO_STRING: InfoBits = 1 << 4;
58const INFO_TRUE: InfoBits = 1 << 5;
59const INFO_OBJECT: InfoBits = 1 << 6;
60const INFO_ARRAY: InfoBits = 1 << 7;
61const INFO_ESC: InfoBits = 1 << 8;
63const INFO_SIGN: InfoBits = 1 << 9;
64const INFO_DOT: InfoBits = 1 << 10;
65const INFO_E: InfoBits = 1 << 11;
66const INFO_FOG: InfoBits = 1 << 12;
67
68static KINDMAP: [Kind; 256] = {
69 let mut map = [Kind::Null; 256];
70 map[INFO_NULL as usize] = Kind::Null;
71 map[INFO_FALSE as usize] = Kind::False;
72 map[INFO_NUMBER as usize] = Kind::Number;
73 map[INFO_STRING as usize] = Kind::String;
74 map[INFO_TRUE as usize] = Kind::True;
75 map[INFO_OBJECT as usize] = Kind::Object;
76 map[INFO_ARRAY as usize] = Kind::Array;
77 map
78};
79
80pub struct Value<'a> {
82 slice: &'a str,
83 owned: String,
84 uescstr: String,
85 info: InfoBits,
86 index: Option<usize>,
87}
88
89impl<'a> Eq for Value<'a> {}
90
91impl<'a> PartialOrd for Value<'a> {
92 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
93 Some(self.cmp(other))
94 }
95}
96
97impl<'a> PartialEq for Value<'a> {
98 fn eq(&self, other: &Self) -> bool {
99 self.cmp(&other) == Ordering::Equal
100 }
101}
102
103impl<'a> Ord for Value<'a> {
104 fn cmp(&self, other: &Self) -> Ordering {
105 let cmp = self.kind().cmp(&other.kind());
106 if cmp != Ordering::Equal {
107 cmp
108 } else if self.kind() == Kind::String {
109 self.str().cmp(other.str())
110 } else if self.kind() == Kind::Number {
111 let x = self.f64();
112 let y = other.f64();
113 if x < y {
114 Ordering::Less
115 } else if x > y {
116 Ordering::Greater
117 } else {
118 Ordering::Equal
119 }
120 } else {
121 self.json().cmp(other.json())
122 }
123 }
124}
125
126impl<'a> Default for Value<'a> {
127 fn default() -> Self {
128 return Value {
129 slice: "",
130 owned: String::default(),
131 uescstr: String::default(),
132 info: 0,
133 index: None,
134 };
135 }
136}
137
138impl<'a> fmt::Display for Value<'a> {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(f, "{}", self.str())
141 }
142}
143
144fn json_clone_from_ref<'a>(json: &'a Value<'a>) -> Value<'a> {
145 Value {
146 slice: json.json(),
147 owned: String::new(),
148 uescstr: json.uescstr.to_owned(),
149 info: json.info,
150 index: json.index,
151 }
152}
153
154fn json_from_slice<'a>(slice: &'a [u8], index: Option<usize>, info: InfoBits) -> Value<'a> {
155 let mut json = Value {
156 slice: tostr(slice),
157 owned: String::new(),
158 uescstr: String::new(),
159 info,
160 index,
161 };
162 json_unescape_string(&mut json);
163 return json;
164}
165
166fn json_from_owned<'a>(owned: String, index: Option<usize>, info: InfoBits) -> Value<'a> {
167 let mut json = Value {
168 slice: "",
169 owned: owned,
170 uescstr: String::new(),
171 info,
172 index,
173 };
174 json_unescape_string(&mut json);
175 return json;
176}
177
178fn json_unescape_string<'a>(json: &mut Value<'a>) {
179 if json.info & (INFO_STRING | INFO_ESC) == (INFO_STRING | INFO_ESC) {
180 json.uescstr = unescape(json.json());
182 }
183}
184
185impl<'a> Value<'a> {
186 pub fn get(&'a self, path: &'a str) -> Value<'a> {
187 let mut json = if self.slice.len() > 0 {
188 get(&self.slice, path)
189 } else {
190 json_into_owned(get(&self.owned, path))
191 };
192 let mut index = None;
193 if let Some(index1) = self.index {
194 if let Some(index2) = json.index {
195 index = Some(index1 + index2);
196 }
197 }
198 json.index = index;
199 json
200 }
201
202 pub fn exists(&self) -> bool {
203 self.json().len() > 0
204 }
205
206 pub fn kind(&self) -> Kind {
207 KINDMAP[(self.info << 24 >> 24) as usize]
208 }
209
210 pub fn json(&self) -> &str {
211 if self.owned.len() > 0 {
212 self.owned.as_str()
213 } else {
214 self.slice
215 }
216 }
217
218 pub fn f64(&'a self) -> f64 {
219 let raw = self.json().as_bytes();
220 match self.kind() {
221 Kind::True => 1.0,
222 Kind::String => {
223 if self.info & INFO_ESC == INFO_ESC {
224 raw_to_f64(&unescape(tostr(raw)))
225 } else {
226 raw_to_f64(tostr(&raw[1..raw.len() - 1]))
227 }
228 }
229 Kind::Number => raw_to_f64(tostr(raw)),
230 _ => 0.0,
231 }
232 }
233
234 pub fn f32(&'a self) -> f32 {
235 self.f64() as f32
236 }
237
238 pub fn i64(&'a self) -> i64 {
239 let raw = self.json().as_bytes();
240 match self.kind() {
241 Kind::True => 1,
242 Kind::String => {
243 if self.info & INFO_ESC == INFO_ESC {
244 raw_to_i64(&unescape(tostr(raw)))
245 } else {
246 raw_to_i64(tostr(&raw[1..raw.len() - 1]))
247 }
248 }
249 Kind::Number => raw_to_i64(tostr(raw)),
250 _ => 0,
251 }
252 }
253
254 pub fn u64(&'a self) -> u64 {
255 let raw = self.json().as_bytes();
256 match self.kind() {
257 Kind::True => 1,
258 Kind::String => {
259 if self.info & INFO_ESC == INFO_ESC {
260 raw_to_u64(&unescape(tostr(raw)))
261 } else {
262 raw_to_u64(tostr(&raw[1..raw.len() - 1]))
263 }
264 }
265 Kind::Number => raw_to_u64(tostr(raw)),
266 _ => 0,
267 }
268 }
269
270 pub fn i32(&'a self) -> i32 {
271 let x = self.i64();
272 (if x < -2147483648 {
273 -2147483648
274 } else if x > 2147483648 {
275 2147483648
276 } else {
277 x
278 }) as i32
279 }
280
281 pub fn i16(&'a self) -> i16 {
282 let x = self.i64();
283 (if x < -32768 {
284 -32768
285 } else if x > 32767 {
286 32767
287 } else {
288 x
289 }) as i16
290 }
291
292 pub fn i8(&'a self) -> i8 {
293 let x = self.i64();
294 (if x < -128 {
295 -128
296 } else if x > 127 {
297 127
298 } else {
299 x
300 }) as i8
301 }
302
303 pub fn u32(&'a self) -> u32 {
304 let x = self.u64();
305 (if x > 4294967295 { 4294967295 } else { x }) as u32
306 }
307
308 pub fn u16(&'a self) -> u16 {
309 let x = self.u64();
310 (if x > 65535 { 65535 } else { x }) as u16
311 }
312
313 pub fn u8(&'a self) -> u8 {
314 let x = self.u64();
315 (if x > 255 { 255 } else { x }) as u8
316 }
317
318 pub fn bool(&'a self) -> bool {
319 let raw = self.json();
320 match raw {
321 r#"1"# | r#"true"# => true,
322 r#"0"# | r#"false"# => false,
323
324 r#""t""# | r#""1""# | r#""T""# => true,
325 r#""f""# | r#""0""# | r#""F""# => false,
326
327 r#""true""# | r#""TRUE""# | r#""True""# => true,
328 r#""false""# | r#""FALSE""# | r#""False""# => false,
329 _ => self.i64() != 0,
330 }
331 }
332
333 pub fn str(&'a self) -> &'a str {
334 match self.kind() {
335 Kind::True => "true",
336 Kind::False => "false",
337 Kind::Object | Kind::Array | Kind::Number => self.json(),
338 Kind::String => {
339 if self.info & INFO_ESC == INFO_ESC {
340 self.uescstr.as_ref()
341 } else {
342 let raw = self.json().as_bytes();
343 tostr(&raw[1..raw.len() - 1])
344 }
345 }
346 Kind::Null => "",
349 }
350 }
351
352 pub fn each(&'a self, mut iter: impl FnMut(Value<'a>, Value<'a>) -> bool) {
353 if !self.exists() {
354 return;
355 }
356 let kind = self.kind();
357 if kind != Kind::Object && kind != Kind::Array {
358 iter(Value::default(), json_clone_from_ref(&self));
359 return;
360 }
361 let json = self.json().as_bytes();
362 for_each(json, 0, false, kind, iter);
363 }
364
365 pub fn array(&'a self) -> Vec<Value<'a>> {
366 let mut arr = Vec::new();
367 if self.kind() == Kind::Array {
368 self.each(|_, value| {
369 arr.push(value);
370 true
371 })
372 }
373 arr
374 }
375}
376
377fn for_each<'a>(
378 json: &'a [u8],
379 mut i: usize,
380 lines: bool,
381 kind: Kind,
382 mut iter: impl FnMut(Value<'a>, Value<'a>) -> bool,
383) -> usize {
384 if i == json.len() {
385 return i;
386 }
387 if !lines {
388 i += 1;
389 }
390 let mut index = 0;
391 let mut tmp_key = Value::default();
392 while i < json.len() {
393 if json[i] <= b' ' || json[i] == b',' || json[i] == b':' {
394 i += 1;
395 continue;
396 }
397 if json[i] == b'}' || json[i] == b']' {
398 return i + 1;
399 }
400 let (res, next_i, _) = proc_value(json, i, Path::default(), true);
401 i = next_i;
402 if res.exists() {
403 if kind == Kind::Object {
404 if index % 2 == 0 {
405 tmp_key = res;
406 } else {
407 let key = tmp_key;
408 tmp_key = Value::default();
409 if !iter(key, res) {
410 break;
411 }
412 }
413 } else {
414 if !iter(Value::default(), res) {
415 break;
416 }
417 }
418 index += 1;
419 }
420 }
421 i
422}
423
424fn raw_to_f64(raw: &str) -> f64 {
425 raw.parse().unwrap_or(0.0)
426}
427
428fn raw_to_i64(raw: &str) -> i64 {
429 raw.parse().unwrap_or(raw_to_f64(raw) as i64)
430}
431
432fn raw_to_u64(raw: &str) -> u64 {
433 raw.parse().unwrap_or(raw_to_f64(raw) as u64)
434}
435
436const CHQUOTE: u8 = 1 << 1;
437const CHOPEN: u8 = 1 << 2;
438const CHCLOSE: u8 = 1 << 3;
439const CHSTRTOK: u8 = 1 << 4;
440const CHSQUASH: u8 = 1 << 5;
441
442static CHTABLE: [u8; 256] = {
443 let mut table = [0; 256];
444 table[b'{' as usize] |= CHSQUASH | CHOPEN;
445 table[b'[' as usize] |= CHSQUASH | CHOPEN;
446 table[b'(' as usize] |= CHSQUASH | CHOPEN;
447 table[b'}' as usize] |= CHSQUASH | CHCLOSE;
448 table[b']' as usize] |= CHSQUASH | CHCLOSE;
449 table[b')' as usize] |= CHSQUASH | CHCLOSE;
450 table[b'"' as usize] |= CHSQUASH | CHQUOTE;
451 table[b'\\' as usize] |= CHSQUASH;
452 table[b'"' as usize] |= CHSTRTOK;
453 table[b'\\' as usize] |= CHSTRTOK;
454 table
455};
456
457fn scan_number<'a>(json: &'a [u8], mut i: usize) -> (&'a [u8], InfoBits, usize) {
459 let s = i;
460 let mut info = 0;
461 if json[i] == b'-' {
462 info |= INFO_SIGN;
463 }
464 i += 1;
465 while i < json.len() {
466 let ch = json[i];
467 if ch == b'.' {
468 info |= INFO_DOT;
469 } else if ch == b'e' || ch == b'E' {
470 info |= INFO_E;
471 } else if (ch < b'0' || ch > b'9') && ch != b'-' && ch != b'+' {
472 break;
473 }
474 i += 1;
475 }
476 (&json[s..i], info, i)
477}
478
479#[inline(always)]
480fn scan_string<'a>(json: &'a [u8], mut i: usize) -> (&'a [u8], InfoBits, usize) {
481 let mut info = 0;
482 let s = i;
483 i += 1;
484 'outer: loop {
485 let mut ch;
486 'tok: loop {
487 while i + 8 < json.len() {
488 for _ in 0..8 {
489 ch = unsafe { *json.get_unchecked(i) } as usize;
491 if CHTABLE[ch] & CHSTRTOK == CHSTRTOK {
492 break 'tok;
493 }
494 i += 1;
495 }
496 }
497 while i < json.len() {
498 ch = json[i] as usize;
499 if CHTABLE[ch] & CHSTRTOK == CHSTRTOK {
500 break 'tok;
501 }
502 i += 1;
503 }
504 break 'outer;
505 }
506 if ch as u8 == b'"' {
507 i += 1;
508 return (&json[s..i], info, i);
509 } else {
510 info |= INFO_ESC;
512 i += 1;
513 if i == json.len() {
514 break;
515 }
516 i += 1;
517 }
518 }
519 ("".as_bytes(), 0, json.len())
520}
521
522fn scan_squash<'a>(json: &'a [u8], mut i: usize) -> (&'a [u8], usize) {
524 let s = i;
525 i += 1;
526 let mut depth = 1;
527 'outer: loop {
528 let mut ch;
529 'tok: loop {
530 while i + 8 < json.len() {
531 for _ in 0..8 {
532 ch = unsafe { *json.get_unchecked(i) } as usize;
534 if CHTABLE[ch] & CHSQUASH == CHSQUASH {
535 break 'tok;
536 }
537 i += 1;
538 }
539 }
540 while i < json.len() {
541 ch = json[i] as usize;
542 if CHTABLE[ch] & CHSQUASH == CHSQUASH {
543 break 'tok;
544 }
545 i += 1;
546 }
547 break 'outer;
548 }
549 if ch as u8 == b'"' {
550 i = scan_string(json, i).2;
551 continue;
552 } else if CHTABLE[ch] & CHOPEN == CHOPEN {
553 depth += 1;
554 } else if CHTABLE[ch] & CHCLOSE == CHCLOSE {
555 depth -= 1;
556 if depth == 0 {
557 i += 1;
558 return (&json[s..i], i);
559 }
560 } else if ch == b'\\' as usize {
561 i += 1;
562 if i == json.len() {
563 break 'outer;
564 }
565 }
566 i += 1;
567 }
568 ("".as_bytes(), json.len())
569}
570
571fn proc_value<'a>(
572 json: &'a [u8],
573 mut i: usize,
574 path: Path<'a>,
575 is_match: bool,
576) -> (Value<'a>, usize, Path<'a>) {
577 if json[i] == b'"' {
578 let s = i;
579 let (val, info, next_i) = scan_string(json, i);
580 i = next_i;
581 if is_match {
582 return (json_from_slice(val, Some(s), info | INFO_STRING), i, path);
583 }
584 } else if json[i] == b'{' || json[i] == b'[' {
585 if is_match {
586 let mut squash = true;
587 if path.sep == b'.' {
588 let next_path = path.next();
589 if !next_path.is_modifier() && !next_path.is_multipath() {
590 squash = false;
591 let (res, next_i, next_path) = if json[i] == b'{' {
592 get_obj(json, i, next_path)
593 } else {
594 get_arr(json, i, false, next_path)
595 };
596 if res.exists() {
597 return (res, next_i, next_path);
598 }
599 }
600 }
601 if squash {
602 let s = i;
604 let (val, next_i) = scan_squash(json, i);
605 i = next_i;
606 let kind = if json[s] == b'{' {
607 INFO_OBJECT
608 } else {
609 INFO_ARRAY
610 };
611 return (json_from_slice(val, Some(s), 0 | kind), i, path);
612 }
613 } else {
614 i = scan_squash(json, i).1;
615 }
616 } else if (json[i] >= b'0' && json[i] <= b'9') || json[i] == b'-' {
617 let s = i;
618 let (val, info, next_i) = scan_number(json, i);
619 i = next_i;
620 if is_match {
621 return (json_from_slice(val, Some(s), info | INFO_NUMBER), i, path);
622 }
623 } else {
624 let s = i;
625 let kind;
626 if json[i] == b't' {
627 if i + 3 >= json.len() {
628 return (Value::default(), json.len(), path);
629 }
630 i += 4;
631 kind = INFO_TRUE;
632 } else if json[i] == b'f' {
633 if i + 4 >= json.len() {
634 return (Value::default(), json.len(), path);
635 }
636 i += 5;
637 kind = INFO_FALSE;
638 } else if json[i] == b'n' {
639 if i + 3 >= json.len() {
640 return (Value::default(), json.len(), path);
641 }
642 i += 4;
643 kind = INFO_NULL;
644 } else {
645 return (Value::default(), json.len(), Path::default());
647 }
648 if is_match {
649 return (json_from_slice(&json[s..i], Some(s), kind), i, path);
650 }
651 }
652 (Value::default(), i, path)
653}
654
655fn get_obj<'a>(json: &'a [u8], mut i: usize, path: Path<'a>) -> (Value<'a>, usize, Path<'a>) {
656 if i == json.len() || json[i] != b'{' {
657 return (Value::default(), i, path);
658 }
659 i += 1;
660 while i < json.len() {
661 if json[i] == b'}' {
662 i += 1;
663 break;
664 }
665 if json[i] != b'"' {
666 i += 1;
667 continue;
668 }
669 let (key, info, next_i) = scan_string(json, i);
671 i = next_i;
672 while i < json.len() {
673 if json[i] <= b' ' || json[i] == b':' {
674 i += 1;
675 continue;
676 }
677 break;
678 }
679 if i == json.len() {
680 break;
681 }
682 let is_match = key_match(key, info, &path);
683 let (res, next_i, next_path) = proc_value(json, i, path, is_match);
684 i = next_i;
685 if res.exists() {
686 return (res, i, next_path);
687 }
688 }
689 (Value::default(), i, path)
690}
691
692fn key_match(key: &[u8], info: InfoBits, path: &Path) -> bool {
693 let comp = tostr(path.comp);
694 if info & INFO_ESC == INFO_ESC {
695 let key = unescape(tostr(key));
696 if path.pat || path.esc {
697 pmatch(comp, key)
698 } else {
699 key.eq(comp)
700 }
701 } else {
702 let key = tostr(&key[1..key.len() - 1]);
703 if path.pat || path.esc {
704 pmatch(comp, key)
705 } else {
706 key.eq(comp)
707 }
708 }
709}
710
711fn get_arr<'a>(
712 json: &'a [u8],
713 i: usize,
714 lines: bool,
715 path: Path<'a>,
716) -> (Value<'a>, usize, Path<'a>) {
717 if path.comp.len() > 0 && path.comp[0] == b'#' {
733 if path.comp.len() == 1 {
734 if path.sep == b'.' {
735 get_arr_children_with_subpath(json, i, lines, path)
736 } else {
737 get_arr_count(json, i, lines, path)
738 }
739 } else if path.comp[path.comp.len() - 1] == b'#' {
740 get_arr_children_with_query_subpath(json, i, lines, path)
741 } else {
742 get_arr_child_with_query(json, i, lines, path)
743 }
744 } else {
745 get_arr_child_at_index(json, i, lines, path)
746 }
747}
748
749fn get_arr_count<'a>(
750 json: &'a [u8],
751 mut i: usize,
752 lines: bool,
753 path: Path<'a>,
754) -> (Value<'a>, usize, Path<'a>) {
755 let mut count = 0;
756 i = for_each(json, i, lines, Kind::Array, |_, _| {
757 count += 1;
758 true
759 });
760 let res = json_from_owned(format!("{}", count), None, INFO_NUMBER);
761 (res, i, path)
762}
763
764fn get_arr_child_at_index<'a>(
765 json: &'a [u8],
766 mut i: usize,
767 lines: bool,
768 path: Path<'a>,
769) -> (Value<'a>, usize, Path<'a>) {
770 let comp_index = tostr(path.comp).parse::<i64>().unwrap_or(-1);
771 let mut res = Value::default();
772 let mut index = 0;
773 let mut next_i = 0;
774 i = for_each(json, i, lines, Kind::Array, |_, value| {
775 if index == comp_index {
776 res = value;
777 next_i = i;
778 return false;
779 }
780 index += 1;
781 true
782 });
783 if res.exists() {
784 (res, next_i, path)
785 } else {
786 (Value::default(), i, path)
787 }
788}
789
790fn query_matches<'a>(valin: &Value<'a>, op: &str, rpv: &str) -> bool {
791 let uesc_str: String;
792 let mut rpv = rpv.as_bytes();
793 if rpv.len() > 2 && rpv[0] == b'"' && rpv[rpv.len() - 1] == b'"' {
794 let mut overwrite = false;
795 for c in rpv {
796 if *c == b'\\' {
797 overwrite = true;
798 uesc_str = unescape(tostr(rpv));
799 rpv = uesc_str.as_bytes();
800 break;
801 }
802 }
803 if !overwrite {
804 rpv = &rpv[1..rpv.len() - 1];
805 }
806 }
807 let mut value = valin;
808 let mut tvalue = Value::default();
809 if rpv.len() > 0 && rpv[0] == b'~' {
810 rpv = &rpv[1..];
812 if value.bool() {
813 tvalue.slice = "true";
814 tvalue.info = INFO_TRUE;
815 } else {
816 tvalue.slice = "false";
817 tvalue.info = INFO_FALSE;
818 }
819 value = &tvalue;
820 }
821 let rpv = tostr(rpv);
822 if !value.exists() {
823 return false;
824 }
825 if op == "" {
826 return true;
831 }
832 match value.kind() {
833 Kind::String => match op {
834 "=" => value.str() == rpv,
835 "!=" => value.str() != rpv,
836 "<" => value.str() < rpv,
837 "<=" => value.str() <= rpv,
838 ">" => value.str() > rpv,
839 ">=" => value.str() >= rpv,
840 "%" => pmatch(rpv, value.str()),
841 "!%" => !pmatch(rpv, value.str()),
842 _ => false,
843 },
844 Kind::Number => {
845 let rpvn = rpv.parse().unwrap_or(0.0);
846 match op {
847 "=" => value.f64() == rpvn,
848 "!=" => value.f64() != rpvn,
849 "<" => value.f64() < rpvn,
850 "<=" => value.f64() <= rpvn,
851 ">" => value.f64() > rpvn,
852 ">=" => value.f64() >= rpvn,
853 _ => false,
854 }
855 }
856 Kind::True => match op {
857 "=" => rpv == "true",
858 "!=" => rpv != "true",
859 ">" => rpv == "false",
860 ">=" => true,
861 _ => false,
862 },
863 Kind::False => match op {
864 "=" => rpv == "false",
865 "!=" => rpv != "false",
866 "<" => rpv == "true",
867 "<=" => true,
868 _ => false,
869 },
870 _ => false,
871 }
872}
873
874fn get_arr_child_with_query<'a>(
875 json: &'a [u8],
876 mut i: usize,
877 lines: bool,
878 path: Path<'a>,
879) -> (Value<'a>, usize, Path<'a>) {
880 let (lh, op, rhv) = path.query_parts();
881 let mut res = Value::default();
882 i = for_each(json, i, lines, Kind::Array, |_, value| {
883 let is_match = if lh != "" {
884 query_matches(&value.get(lh), op, rhv)
885 } else {
886 query_matches(&value, op, rhv)
887 };
888 if is_match {
889 res = value;
890 return false;
891 }
892 true
893 });
894 if res.exists() {
895 (res, i, path)
896 } else {
897 (Value::default(), i, path)
898 }
899}
900
901fn get_arr_children_with_query_subpath<'a>(
902 json: &'a [u8],
903 mut i: usize,
904 lines: bool,
905 mut path: Path<'a>,
906) -> (Value<'a>, usize, Path<'a>) {
907 let (lh, op, rhv) = path.query_parts();
908 let mut subpath = None;
909 let r = path.next_group();
910 if path.sep == b'.' {
911 subpath = Some(r.0);
912 }
913 path = r.1;
914 let mut res = Vec::new();
915 res.push(b'[');
916 let mut index = 0;
917 i = for_each(json, i, lines, Kind::Array, |_, value| {
918 let is_match = if lh != "" {
919 query_matches(&value.get(lh), op, rhv)
920 } else {
921 query_matches(&value, op, rhv)
922 };
923 if is_match {
924 let value = if let Some(subpath) = subpath {
925 value.get(subpath)
926 } else {
927 value
928 };
929 if value.exists() {
930 if index > 0 {
931 res.push(b',');
932 }
933 res.extend(value.json().as_bytes());
934 index += 1;
935 }
936 }
937 true
938 });
939 res.push(b']');
940 let res = json_from_owned(
941 unsafe { String::from_utf8_unchecked(res) },
943 None,
944 INFO_ARRAY,
945 );
946 (res, i, path)
947}
948
949fn get_arr_children_with_subpath<'a>(
950 json: &'a [u8],
951 mut i: usize,
952 lines: bool,
953 mut path: Path<'a>,
954) -> (Value<'a>, usize, Path<'a>) {
955 let r = path.next_group();
956 let subpath = r.0;
957 path = r.1;
958 let mut res = Vec::new();
959 res.push(b'[');
960 let mut index = 0;
961 i = for_each(json, i, lines, Kind::Array, |_, value| {
962 let value = value.get(subpath);
963 if value.exists() {
964 if index > 0 {
965 res.push(b',');
966 }
967 res.extend(value.json().as_bytes());
968 index += 1;
969 }
970 true
971 });
972 res.push(b']');
973 let res = json_from_owned(
974 unsafe { String::from_utf8_unchecked(res) },
976 None,
977 INFO_ARRAY,
978 );
979 (res, i, path)
980}
981
982#[inline]
1021pub fn get<'a>(json: &'a str, path: &'a str) -> Value<'a> {
1022 let mut path = path;
1023 let mut lines = false;
1024 if path.len() >= 2 && path.as_bytes()[0] == b'.' && path.as_bytes()[1] == b'.' {
1025 path = tostr(&path.as_bytes()[2..]);
1027 lines = true;
1028 }
1029 let path = Path::new(path);
1030 let (res, path) = {
1031 let json = json.as_bytes();
1032 if lines {
1033 let res = get_arr(json, 0, true, path);
1034 (res.0, res.2)
1035 } else if path.is_modifier() {
1036 modifiers::exec(json, path)
1037 } else if path.is_multipath() {
1038 multipath::exec(json, path)
1039 } else {
1040 let mut i = 0;
1041 loop {
1042 if i == json.len() {
1043 break (Value::default(), path);
1044 }
1045 if json[i] <= b' ' {
1046 i += 1;
1047 continue;
1048 }
1049 if json[i] == b'{' {
1050 let res = get_obj(json, i, path);
1051 break (res.0, res.2);
1052 }
1053 if json[i] == b'[' {
1054 let res = get_arr(json, i, false, path);
1055 break (res.0, res.2);
1056 }
1057 break (Value::default(), path);
1058 }
1059 }
1060 };
1061 if !path.more() {
1062 return res;
1063 }
1064 let path = tostr(path.extra);
1065 let mut json = if res.slice.len() > 0 {
1066 get(&res.slice, path)
1067 } else {
1068 json_into_owned(get(&res.owned, path))
1069 };
1070 let mut index = None;
1071 if let Some(index1) = res.index {
1072 if let Some(index2) = json.index {
1073 index = Some(index1 + index2);
1074 }
1075 }
1076 json.index = index;
1077 json
1078}
1079
1080pub unsafe fn get_bytes<'a>(json: &'a [u8], path: &'a str) -> Value<'a> {
1091 return get(tostr(json), path)
1092}
1093
1094fn json_into_owned<'a>(json: Value) -> Value<'a> {
1095 Value {
1096 slice: "",
1097 owned: if json.slice.len() > 0 {
1098 json.slice.to_owned()
1099 } else {
1100 json.owned
1101 },
1102 uescstr: json.uescstr,
1103 info: json.info,
1104 index: json.index,
1105 }
1106}
1107
1108pub fn parse<'a>(json: &'a str) -> Value<'a> {
1115 let json = json.as_bytes();
1116 let mut i = 0;
1117 while i < json.len() {
1118 if json[i] <= b' ' {
1119 i += 1;
1120 continue;
1121 }
1122 match json[i] {
1123 b'{' => return json_from_slice(&json[i..], Some(i), INFO_OBJECT | INFO_FOG),
1124 b'[' => return json_from_slice(&json[i..], Some(i), INFO_ARRAY | INFO_FOG),
1125 b't' | b'f' | b'n' | b'"' | b'0' | b'1' | b'2' => {}
1126 b'3' | b'4' | b'5' | b'6' | b'7' | b'8' | b'9' | b'-' => {}
1127 _ => break,
1128 }
1129 return proc_value(json, i, Path::default(), true).0;
1130 }
1131 return Value::default();
1132}