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