1use core::convert::TryInto;
16use std::borrow::Cow;
17use std::cmp::Ordering;
18use std::collections::VecDeque;
19
20use super::constants::*;
21use super::error::*;
22use super::jentry::JEntry;
23use super::json_path::JsonPathRef;
24use super::number::Number;
25use super::parser::decode_value;
26use super::value::Value;
27
28pub fn build_array<'a>(
34 items: impl IntoIterator<Item = &'a [u8]>,
35 buf: &mut Vec<u8>,
36) -> Result<(), Error> {
37 let start = buf.len();
38 buf.resize(start + 4, 0);
40 let mut len: u32 = 0;
41 let mut data = Vec::new();
42 for value in items.into_iter() {
43 let header = read_u32(value, 0)?;
44 let encoded_jentry = match header & CONTAINER_HEADER_TYPE_MASK {
45 SCALAR_CONTAINER_TAG => {
46 let jentry = &value[4..8];
47 data.extend_from_slice(&value[8..]);
48 jentry.try_into().unwrap()
49 }
50 ARRAY_CONTAINER_TAG | OBJECT_CONTAINER_TAG => {
51 data.extend_from_slice(value);
52 (CONTAINER_TAG | value.len() as u32).to_be_bytes()
53 }
54 _ => return Err(Error::InvalidJsonbHeader),
55 };
56 len += 1;
57 buf.extend_from_slice(&encoded_jentry);
58 }
59 let header = ARRAY_CONTAINER_TAG | len;
61 for (i, b) in header.to_be_bytes().iter().enumerate() {
62 buf[start + i] = *b;
63 }
64 buf.extend_from_slice(&data);
65
66 Ok(())
67}
68
69pub fn build_object<'a, K: AsRef<str>>(
72 items: impl IntoIterator<Item = (K, &'a [u8])>,
73 buf: &mut Vec<u8>,
74) -> Result<(), Error> {
75 let start = buf.len();
76 buf.resize(start + 4, 0);
78 let mut len: u32 = 0;
79 let mut key_data = Vec::new();
80 let mut val_data = Vec::new();
81 let mut val_jentries = VecDeque::new();
82 for (key, value) in items.into_iter() {
83 let key = key.as_ref();
84 let encoded_key_jentry = (STRING_TAG | key.len() as u32).to_be_bytes();
86 buf.extend_from_slice(&encoded_key_jentry);
87 key_data.extend_from_slice(key.as_bytes());
88
89 let header = read_u32(value, 0)?;
91 let encoded_val_jentry = match header & CONTAINER_HEADER_TYPE_MASK {
92 SCALAR_CONTAINER_TAG => {
93 let jentry = &value[4..8];
94 val_data.extend_from_slice(&value[8..]);
95 jentry.try_into().unwrap()
96 }
97 ARRAY_CONTAINER_TAG | OBJECT_CONTAINER_TAG => {
98 val_data.extend_from_slice(value);
99 (CONTAINER_TAG | value.len() as u32).to_be_bytes()
100 }
101 _ => return Err(Error::InvalidJsonbHeader),
102 };
103 val_jentries.push_back(encoded_val_jentry);
104 len += 1;
105 }
106 let header = OBJECT_CONTAINER_TAG | len;
108 for (i, b) in header.to_be_bytes().iter().enumerate() {
109 buf[start + i] = *b;
110 }
111 while let Some(val_jentry) = val_jentries.pop_front() {
112 buf.extend_from_slice(&val_jentry);
113 }
114 buf.extend_from_slice(&key_data);
116 buf.extend_from_slice(&val_data);
117
118 Ok(())
119}
120
121pub fn array_length(value: &[u8]) -> Option<usize> {
123 if !is_jsonb(value) {
124 let json_value = decode_value(value).unwrap();
125 return json_value.array_length();
126 }
127 let header = read_u32(value, 0).unwrap();
128 match header & CONTAINER_HEADER_TYPE_MASK {
129 ARRAY_CONTAINER_TAG => {
130 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
131 Some(length)
132 }
133 _ => None,
134 }
135}
136
137pub fn get_by_name_ignore_case(value: &[u8], name: &str) -> Option<Vec<u8>> {
139 if !is_jsonb(value) {
140 let json_value = decode_value(value).unwrap();
141 return json_value.get_by_name_ignore_case(name).map(Value::to_vec);
142 }
143
144 let header = read_u32(value, 0).unwrap();
145 match header & CONTAINER_HEADER_TYPE_MASK {
146 OBJECT_CONTAINER_TAG => {
147 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
148 let mut jentry_offset = 4;
149 let mut val_offset = 8 * length + 4;
150
151 let mut key_jentries: VecDeque<JEntry> = VecDeque::with_capacity(length);
152 for _ in 0..length {
153 let encoded = read_u32(value, jentry_offset).unwrap();
154 let key_jentry = JEntry::decode_jentry(encoded);
155
156 jentry_offset += 4;
157 val_offset += key_jentry.length as usize;
158 key_jentries.push_back(key_jentry);
159 }
160
161 let mut offsets = None;
162 let mut key_offset = 8 * length + 4;
163 while let Some(key_jentry) = key_jentries.pop_front() {
164 let prev_key_offset = key_offset;
165 key_offset += key_jentry.length as usize;
166 let key =
167 unsafe { std::str::from_utf8_unchecked(&value[prev_key_offset..key_offset]) };
168 if name.eq(key) {
171 offsets = Some((jentry_offset, val_offset));
172 break;
173 } else if name.eq_ignore_ascii_case(key) && offsets.is_none() {
174 offsets = Some((jentry_offset, val_offset));
175 }
176 let val_encoded = read_u32(value, jentry_offset).unwrap();
177 let val_jentry = JEntry::decode_jentry(val_encoded);
178 jentry_offset += 4;
179 val_offset += val_jentry.length as usize;
180 }
181 if let Some((jentry_offset, mut val_offset)) = offsets {
182 let mut buf: Vec<u8> = Vec::new();
183 let encoded = read_u32(value, jentry_offset).unwrap();
184 let jentry = JEntry::decode_jentry(encoded);
185 let prev_val_offset = val_offset;
186 val_offset += jentry.length as usize;
187 match jentry.type_code {
188 CONTAINER_TAG => buf.extend_from_slice(&value[prev_val_offset..val_offset]),
189 _ => {
190 let scalar_header = SCALAR_CONTAINER_TAG;
191 buf.extend_from_slice(&scalar_header.to_be_bytes());
192 buf.extend_from_slice(&encoded.to_be_bytes());
193 if val_offset > prev_val_offset {
194 buf.extend_from_slice(&value[prev_val_offset..val_offset]);
195 }
196 }
197 }
198 return Some(buf);
199 }
200 None
201 }
202 _ => None,
203 }
204}
205
206pub fn get_by_path<'a>(value: &'a [u8], paths: Vec<JsonPathRef<'a>>) -> Option<Vec<u8>> {
210 if !is_jsonb(value) {
211 let json_value = decode_value(value).unwrap();
212 return json_value.get_by_path(&paths).map(Value::to_vec);
213 }
214
215 let mut offset = 0;
216 let mut buf: Vec<u8> = Vec::new();
217
218 for i in 0..paths.len() {
219 let path = paths.get(i).unwrap();
220 let header = read_u32(value, offset).unwrap();
221 let (jentry_offset, val_offset) = match path {
222 JsonPathRef::String(name) => {
223 if header & CONTAINER_HEADER_TYPE_MASK != OBJECT_CONTAINER_TAG {
224 return None;
225 }
226 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
227 let mut jentry_offset = offset + 4;
228 let mut val_offset = offset + 8 * length + 4;
229
230 let mut key_jentries: VecDeque<JEntry> = VecDeque::with_capacity(length);
231 for _ in 0..length {
232 let encoded = read_u32(value, jentry_offset).unwrap();
233 let key_jentry = JEntry::decode_jentry(encoded);
234
235 jentry_offset += 4;
236 val_offset += key_jentry.length as usize;
237 key_jentries.push_back(key_jentry);
238 }
239
240 let mut found = false;
241 let mut key_offset = offset + 8 * length + 4;
242 while let Some(key_jentry) = key_jentries.pop_front() {
243 let prev_key_offset = key_offset;
244 key_offset += key_jentry.length as usize;
245 let key = unsafe {
246 std::str::from_utf8_unchecked(&value[prev_key_offset..key_offset])
247 };
248 if name.eq(key) {
249 found = true;
250 break;
251 }
252 let val_encoded = read_u32(value, jentry_offset).unwrap();
253 let val_jentry = JEntry::decode_jentry(val_encoded);
254 jentry_offset += 4;
255 val_offset += val_jentry.length as usize;
256 }
257 if !found {
258 return None;
259 }
260 (jentry_offset, val_offset)
261 }
262 JsonPathRef::UInt64(index) => {
263 if header & CONTAINER_HEADER_TYPE_MASK != ARRAY_CONTAINER_TAG {
264 return None;
265 }
266 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
267 if *index as usize >= length {
268 return None;
269 }
270 let mut jentry_offset = offset + 4;
271 let mut val_offset = offset + 4 * length + 4;
272
273 for _ in 0..*index {
274 let encoded = read_u32(value, jentry_offset).unwrap();
275 let jentry = JEntry::decode_jentry(encoded);
276
277 jentry_offset += 4;
278 val_offset += jentry.length as usize;
279 }
280 (jentry_offset, val_offset)
281 }
282 };
283 let encoded = read_u32(value, jentry_offset).unwrap();
284 let jentry = JEntry::decode_jentry(encoded);
285 match jentry.type_code {
288 CONTAINER_TAG => {
289 if i == paths.len() - 1 {
290 buf.extend_from_slice(&value[val_offset..val_offset + jentry.length as usize]);
291 } else {
292 offset = val_offset;
293 }
294 }
295 _ => {
296 if i == paths.len() - 1 {
297 let scalar_header = SCALAR_CONTAINER_TAG;
298 buf.extend_from_slice(&scalar_header.to_be_bytes());
299 buf.extend_from_slice(&encoded.to_be_bytes());
300 if jentry.length > 0 {
301 buf.extend_from_slice(
302 &value[val_offset..val_offset + jentry.length as usize],
303 );
304 }
305 } else {
306 return None;
307 }
308 }
309 }
310 }
311 Some(buf)
312}
313
314pub fn object_keys(value: &[u8]) -> Option<Vec<u8>> {
316 if !is_jsonb(value) {
317 let json_value = decode_value(value).unwrap();
318 return json_value.object_keys().map(|val| val.to_vec());
319 }
320
321 let header = read_u32(value, 0).unwrap();
322 match header & CONTAINER_HEADER_TYPE_MASK {
323 OBJECT_CONTAINER_TAG => {
324 let mut buf: Vec<u8> = Vec::new();
325 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
326 let key_header = ARRAY_CONTAINER_TAG | length as u32;
327 buf.extend_from_slice(&key_header.to_be_bytes());
328
329 let mut jentry_offset = 4;
330 let mut key_offset = 8 * length + 4;
331 let mut key_offsets = Vec::with_capacity(length);
332 for _ in 0..length {
333 let key_encoded = read_u32(value, jentry_offset).unwrap();
334 let key_jentry = JEntry::decode_jentry(key_encoded);
335 buf.extend_from_slice(&key_encoded.to_be_bytes());
336
337 jentry_offset += 4;
338 key_offset += key_jentry.length as usize;
339 key_offsets.push(key_offset);
340 }
341 let mut prev_key_offset = 8 * length + 4;
342 for key_offset in key_offsets {
343 if key_offset > prev_key_offset {
344 buf.extend_from_slice(&value[prev_key_offset..key_offset]);
345 }
346 prev_key_offset = key_offset;
347 }
348 Some(buf)
349 }
350 _ => None,
351 }
352}
353
354pub fn compare(left: &[u8], right: &[u8]) -> Result<Ordering, Error> {
359 if !is_jsonb(left) {
360 let lval = decode_value(left).unwrap();
361 let lbuf = lval.to_vec();
362 return compare(&lbuf, right);
363 } else if !is_jsonb(right) {
364 let rval = decode_value(right).unwrap();
365 let rbuf = rval.to_vec();
366 return compare(left, &rbuf);
367 }
368
369 let left_header = read_u32(left, 0)?;
370 let right_header = read_u32(right, 0)?;
371 match (
372 left_header & CONTAINER_HEADER_TYPE_MASK,
373 right_header & CONTAINER_HEADER_TYPE_MASK,
374 ) {
375 (SCALAR_CONTAINER_TAG, SCALAR_CONTAINER_TAG) => {
376 let left_encoded = read_u32(left, 4)?;
377 let left_jentry = JEntry::decode_jentry(left_encoded);
378 let right_encoded = read_u32(right, 4)?;
379 let right_jentry = JEntry::decode_jentry(right_encoded);
380 compare_scalar(&left_jentry, &left[8..], &right_jentry, &right[8..])
381 }
382 (ARRAY_CONTAINER_TAG, ARRAY_CONTAINER_TAG) => {
383 compare_array(left_header, &left[4..], right_header, &right[4..])
384 }
385 (OBJECT_CONTAINER_TAG, OBJECT_CONTAINER_TAG) => {
386 compare_object(left_header, &left[4..], right_header, &right[4..])
387 }
388 (SCALAR_CONTAINER_TAG, ARRAY_CONTAINER_TAG | OBJECT_CONTAINER_TAG) => {
389 let left_encoded = read_u32(left, 4)?;
390 let left_jentry = JEntry::decode_jentry(left_encoded);
391 match left_jentry.type_code {
392 NULL_TAG => Ok(Ordering::Greater),
393 _ => Ok(Ordering::Less),
394 }
395 }
396 (ARRAY_CONTAINER_TAG | OBJECT_CONTAINER_TAG, SCALAR_CONTAINER_TAG) => {
397 let right_encoded = read_u32(right, 4)?;
398 let right_jentry = JEntry::decode_jentry(right_encoded);
399 match right_jentry.type_code {
400 NULL_TAG => Ok(Ordering::Less),
401 _ => Ok(Ordering::Greater),
402 }
403 }
404 (ARRAY_CONTAINER_TAG, OBJECT_CONTAINER_TAG) => Ok(Ordering::Greater),
405 (OBJECT_CONTAINER_TAG, ARRAY_CONTAINER_TAG) => Ok(Ordering::Less),
406 (_, _) => Err(Error::InvalidJsonbHeader),
407 }
408}
409
410fn jentry_compare_level(jentry: &JEntry) -> Result<u8, Error> {
412 match jentry.type_code {
413 NULL_TAG => Ok(5),
414 CONTAINER_TAG => Ok(4),
415 STRING_TAG => Ok(3),
416 NUMBER_TAG => Ok(2),
417 TRUE_TAG => Ok(1),
418 FALSE_TAG => Ok(0),
419 _ => Err(Error::InvalidJsonbJEntry),
420 }
421}
422
423fn compare_scalar(
426 left_jentry: &JEntry,
427 left: &[u8],
428 right_jentry: &JEntry,
429 right: &[u8],
430) -> Result<Ordering, Error> {
431 let left_level = jentry_compare_level(left_jentry)?;
432 let right_level = jentry_compare_level(right_jentry)?;
433 if left_level != right_level {
434 return Ok(left_level.cmp(&right_level));
435 }
436
437 match (left_jentry.type_code, right_jentry.type_code) {
438 (NULL_TAG, NULL_TAG) => Ok(Ordering::Equal),
439 (CONTAINER_TAG, CONTAINER_TAG) => compare_container(left, right),
440 (STRING_TAG, STRING_TAG) => {
441 let left_offset = left_jentry.length as usize;
442 let left_str = unsafe { std::str::from_utf8_unchecked(&left[..left_offset]) };
443 let right_offset = right_jentry.length as usize;
444 let right_str = unsafe { std::str::from_utf8_unchecked(&right[..right_offset]) };
445 Ok(left_str.cmp(right_str))
446 }
447 (NUMBER_TAG, NUMBER_TAG) => {
448 let left_offset = left_jentry.length as usize;
449 let left_num = Number::decode(&left[..left_offset]);
450 let right_offset = right_jentry.length as usize;
451 let right_num = Number::decode(&right[..right_offset]);
452 Ok(left_num.cmp(&right_num))
453 }
454 (TRUE_TAG, TRUE_TAG) => Ok(Ordering::Equal),
455 (FALSE_TAG, FALSE_TAG) => Ok(Ordering::Equal),
456 (_, _) => Err(Error::InvalidJsonbJEntry),
457 }
458}
459
460fn compare_container(left: &[u8], right: &[u8]) -> Result<Ordering, Error> {
461 let left_header = read_u32(left, 0)?;
462 let right_header = read_u32(right, 0)?;
463
464 match (
465 left_header & CONTAINER_HEADER_TYPE_MASK,
466 right_header & CONTAINER_HEADER_TYPE_MASK,
467 ) {
468 (ARRAY_CONTAINER_TAG, ARRAY_CONTAINER_TAG) => {
469 compare_array(left_header, &left[4..], right_header, &right[4..])
470 }
471 (OBJECT_CONTAINER_TAG, OBJECT_CONTAINER_TAG) => {
472 compare_object(left_header, &left[4..], right_header, &right[4..])
473 }
474 (ARRAY_CONTAINER_TAG, OBJECT_CONTAINER_TAG) => Ok(Ordering::Greater),
475 (OBJECT_CONTAINER_TAG, ARRAY_CONTAINER_TAG) => Ok(Ordering::Less),
476 (_, _) => Err(Error::InvalidJsonbHeader),
477 }
478}
479
480fn compare_array(
482 left_header: u32,
483 left: &[u8],
484 right_header: u32,
485 right: &[u8],
486) -> Result<Ordering, Error> {
487 let left_length = (left_header & CONTAINER_HEADER_LEN_MASK) as usize;
488 let right_length = (right_header & CONTAINER_HEADER_LEN_MASK) as usize;
489
490 let mut jentry_offset = 0;
491 let mut left_val_offset = 4 * left_length;
492 let mut right_val_offset = 4 * right_length;
493 let length = if left_length < right_length {
494 left_length
495 } else {
496 right_length
497 };
498 for _ in 0..length {
499 let left_encoded = read_u32(left, jentry_offset)?;
500 let left_jentry = JEntry::decode_jentry(left_encoded);
501 let right_encoded = read_u32(right, jentry_offset)?;
502 let right_jentry = JEntry::decode_jentry(right_encoded);
503
504 let order = compare_scalar(
505 &left_jentry,
506 &left[left_val_offset..],
507 &right_jentry,
508 &right[right_val_offset..],
509 )?;
510 if order != Ordering::Equal {
511 return Ok(order);
512 }
513 jentry_offset += 4;
514
515 left_val_offset += left_jentry.length as usize;
516 right_val_offset += right_jentry.length as usize;
517 }
518
519 Ok(left_length.cmp(&right_length))
520}
521
522fn compare_object(
526 left_header: u32,
527 left: &[u8],
528 right_header: u32,
529 right: &[u8],
530) -> Result<Ordering, Error> {
531 let left_length = (left_header & CONTAINER_HEADER_LEN_MASK) as usize;
532 let right_length = (right_header & CONTAINER_HEADER_LEN_MASK) as usize;
533
534 let mut jentry_offset = 0;
535 let mut left_val_offset = 8 * left_length;
536 let mut right_val_offset = 8 * right_length;
537
538 let length = if left_length < right_length {
539 left_length
540 } else {
541 right_length
542 };
543 let mut left_key_jentries: VecDeque<JEntry> = VecDeque::with_capacity(length);
545 let mut right_key_jentries: VecDeque<JEntry> = VecDeque::with_capacity(length);
546 for _ in 0..length {
547 let left_encoded = read_u32(left, jentry_offset)?;
548 let left_key_jentry = JEntry::decode_jentry(left_encoded);
549 let right_encoded = read_u32(right, jentry_offset)?;
550 let right_key_jentry = JEntry::decode_jentry(right_encoded);
551
552 jentry_offset += 4;
553 left_val_offset += left_key_jentry.length as usize;
554 right_val_offset += right_key_jentry.length as usize;
555
556 left_key_jentries.push_back(left_key_jentry);
557 right_key_jentries.push_back(right_key_jentry);
558 }
559
560 let mut left_jentry_offset = 4 * left_length;
561 let mut right_jentry_offset = 4 * right_length;
562 let mut left_key_offset = 8 * left_length;
563 let mut right_key_offset = 8 * right_length;
564 for _ in 0..length {
565 let left_key_jentry = left_key_jentries.pop_front().unwrap();
567 let right_key_jentry = right_key_jentries.pop_front().unwrap();
568
569 let key_order = compare_scalar(
570 &left_key_jentry,
571 &left[left_key_offset..],
572 &right_key_jentry,
573 &right[right_key_offset..],
574 )?;
575 if key_order != Ordering::Equal {
576 if key_order == Ordering::Greater {
577 return Ok(Ordering::Less);
578 } else {
579 return Ok(Ordering::Greater);
580 }
581 }
582
583 let left_encoded = read_u32(left, left_jentry_offset)?;
584 let left_val_jentry = JEntry::decode_jentry(left_encoded);
585 let right_encoded = read_u32(right, right_jentry_offset)?;
586 let right_val_jentry = JEntry::decode_jentry(right_encoded);
587
588 let val_order = compare_scalar(
589 &left_val_jentry,
590 &left[left_val_offset..],
591 &right_val_jentry,
592 &right[right_val_offset..],
593 )?;
594 if val_order != Ordering::Equal {
595 return Ok(val_order);
596 }
597 left_jentry_offset += 4;
598 right_jentry_offset += 4;
599
600 left_key_offset += left_key_jentry.length as usize;
601 right_key_offset += right_key_jentry.length as usize;
602 left_val_offset += left_val_jentry.length as usize;
603 right_val_offset += right_val_jentry.length as usize;
604 }
605
606 Ok(left_length.cmp(&right_length))
607}
608
609pub fn is_null(value: &[u8]) -> bool {
611 as_null(value).is_some()
612}
613
614pub fn as_null(value: &[u8]) -> Option<()> {
616 if !is_jsonb(value) {
617 if value.is_empty() {
618 return Some(());
619 }
620 let v = value.first().unwrap();
621 if *v == b'n' {
622 return Some(());
623 } else {
624 return None;
625 }
626 }
627 let header = read_u32(value, 0).unwrap();
628 match header & CONTAINER_HEADER_TYPE_MASK {
629 SCALAR_CONTAINER_TAG => {
630 let jentry = read_u32(value, 4).unwrap();
631 match jentry {
632 NULL_TAG => Some(()),
633 _ => None,
634 }
635 }
636 _ => None,
637 }
638}
639
640pub fn is_boolean(value: &[u8]) -> bool {
642 as_bool(value).is_some()
643}
644
645pub fn as_bool(value: &[u8]) -> Option<bool> {
647 if !is_jsonb(value) {
648 let v = value.first().unwrap();
649 if *v == b't' {
650 return Some(true);
651 } else if *v == b'f' {
652 return Some(false);
653 } else {
654 return None;
655 }
656 }
657 let header = read_u32(value, 0).unwrap();
658 match header & CONTAINER_HEADER_TYPE_MASK {
659 SCALAR_CONTAINER_TAG => {
660 let jentry = read_u32(value, 4).unwrap();
661 match jentry {
662 FALSE_TAG => Some(false),
663 TRUE_TAG => Some(true),
664 _ => None,
665 }
666 }
667 _ => None,
668 }
669}
670
671pub fn to_bool(value: &[u8]) -> Result<bool, Error> {
673 if let Some(v) = as_bool(value) {
674 return Ok(v);
675 } else if let Some(v) = as_str(value) {
676 if &v.to_lowercase() == "true" {
677 return Ok(true);
678 } else if &v.to_lowercase() == "false" {
679 return Ok(false);
680 }
681 }
682 Err(Error::InvalidCast)
683}
684
685pub fn is_number(value: &[u8]) -> bool {
687 as_number(value).is_some()
688}
689
690pub fn as_number(value: &[u8]) -> Option<Number> {
692 if !is_jsonb(value) {
693 let json_value = decode_value(value).unwrap();
694 return json_value.as_number().cloned();
695 }
696 let header = read_u32(value, 0).unwrap();
697 match header & CONTAINER_HEADER_TYPE_MASK {
698 SCALAR_CONTAINER_TAG => {
699 let jentry_encoded = read_u32(value, 4).unwrap();
700 let jentry = JEntry::decode_jentry(jentry_encoded);
701 match jentry.type_code {
702 NUMBER_TAG => {
703 let length = jentry.length as usize;
704 let num = Number::decode(&value[8..8 + length]);
705 Some(num)
706 }
707 _ => None,
708 }
709 }
710 _ => None,
711 }
712}
713
714pub fn is_i64(value: &[u8]) -> bool {
716 as_i64(value).is_some()
717}
718
719pub fn to_i64(value: &[u8]) -> Result<i64, Error> {
721 if let Some(v) = as_i64(value) {
722 return Ok(v);
723 } else if let Some(v) = as_bool(value) {
724 if v {
725 return Ok(1_i64);
726 } else {
727 return Ok(0_i64);
728 }
729 } else if let Some(v) = as_str(value) {
730 if let Ok(v) = v.parse::<i64>() {
731 return Ok(v);
732 }
733 }
734 Err(Error::InvalidCast)
735}
736
737pub fn as_i64(value: &[u8]) -> Option<i64> {
739 match as_number(value) {
740 Some(num) => num.as_i64(),
741 None => None,
742 }
743}
744
745pub fn is_u64(value: &[u8]) -> bool {
747 as_u64(value).is_some()
748}
749
750pub fn as_u64(value: &[u8]) -> Option<u64> {
752 match as_number(value) {
753 Some(num) => num.as_u64(),
754 None => None,
755 }
756}
757
758pub fn to_u64(value: &[u8]) -> Result<u64, Error> {
760 if let Some(v) = as_u64(value) {
761 return Ok(v);
762 } else if let Some(v) = as_bool(value) {
763 if v {
764 return Ok(1_u64);
765 } else {
766 return Ok(0_u64);
767 }
768 } else if let Some(v) = as_str(value) {
769 if let Ok(v) = v.parse::<u64>() {
770 return Ok(v);
771 }
772 }
773 Err(Error::InvalidCast)
774}
775
776pub fn is_f64(value: &[u8]) -> bool {
778 as_f64(value).is_some()
779}
780
781pub fn as_f64(value: &[u8]) -> Option<f64> {
783 match as_number(value) {
784 Some(num) => num.as_f64(),
785 None => None,
786 }
787}
788
789pub fn to_f64(value: &[u8]) -> Result<f64, Error> {
791 if let Some(v) = as_f64(value) {
792 return Ok(v);
793 } else if let Some(v) = as_bool(value) {
794 if v {
795 return Ok(1_f64);
796 } else {
797 return Ok(0_f64);
798 }
799 } else if let Some(v) = as_str(value) {
800 if let Ok(v) = v.parse::<f64>() {
801 return Ok(v);
802 }
803 }
804 Err(Error::InvalidCast)
805}
806
807pub fn is_string(value: &[u8]) -> bool {
809 as_str(value).is_some()
810}
811
812pub fn as_str(value: &[u8]) -> Option<Cow<'_, str>> {
814 if !is_jsonb(value) {
815 let v = value.first().unwrap();
816 if *v == b'"' {
817 let s = unsafe { std::str::from_utf8_unchecked(&value[1..value.len() - 1]) };
818 return Some(Cow::Borrowed(s));
819 } else {
820 return None;
821 }
822 }
823 let header = read_u32(value, 0).unwrap();
824 match header & CONTAINER_HEADER_TYPE_MASK {
825 SCALAR_CONTAINER_TAG => {
826 let jentry_encoded = read_u32(value, 4).unwrap();
827 let jentry = JEntry::decode_jentry(jentry_encoded);
828 match jentry.type_code {
829 STRING_TAG => {
830 let length = jentry.length as usize;
831 let s = unsafe { std::str::from_utf8_unchecked(&value[8..8 + length]) };
832 Some(Cow::Borrowed(s))
833 }
834 _ => None,
835 }
836 }
837 _ => None,
838 }
839}
840
841pub fn to_str(value: &[u8]) -> Result<String, Error> {
843 if is_null(value) {
844 return Err(Error::InvalidCast);
845 } else if let Some(v) = as_str(value) {
846 return Ok(v.to_string());
847 }
848 Ok(to_string(value))
849}
850
851pub fn is_array(value: &[u8]) -> bool {
853 if !is_jsonb(value) {
854 let v = value.first().unwrap();
855 return *v == b'[';
856 }
857 let header = read_u32(value, 0).unwrap();
858 matches!(header & CONTAINER_HEADER_TYPE_MASK, ARRAY_CONTAINER_TAG)
859}
860
861pub fn is_object(value: &[u8]) -> bool {
863 if !is_jsonb(value) {
864 let v = value.first().unwrap();
865 return *v == b'{';
866 }
867 let header = read_u32(value, 0).unwrap();
868 matches!(header & CONTAINER_HEADER_TYPE_MASK, OBJECT_CONTAINER_TAG)
869}
870
871pub fn parse_json_path(path: &[u8]) -> Result<Vec<JsonPathRef>, Error> {
874 let mut idx = 0;
875 let mut prev_idx = 0;
876 let mut json_paths = Vec::new();
877 while idx < path.len() {
878 let c = read_char(path, &mut idx)?;
879 if c == b'[' {
880 let c = read_char(path, &mut idx)?;
881 if c == b'"' {
882 prev_idx = idx;
883 loop {
884 let c = read_char(path, &mut idx)?;
885 if c == b'\\' {
886 idx += 1;
887 } else if c == b'"' {
888 let c = read_char(path, &mut idx)?;
889 if c != b']' {
890 return Err(Error::InvalidToken);
891 }
892 break;
893 }
894 }
895 if prev_idx == idx - 2 {
896 return Err(Error::InvalidToken);
897 }
898 let s = std::str::from_utf8(&path[prev_idx..idx - 2])?;
899 let json_path = JsonPathRef::String(Cow::Borrowed(s));
900
901 json_paths.push(json_path);
902 } else {
903 prev_idx = idx - 1;
904 loop {
905 let c = read_char(path, &mut idx)?;
906 if c == b']' {
907 break;
908 }
909 }
910 if prev_idx == idx - 1 {
911 return Err(Error::InvalidToken);
912 }
913 let s = std::str::from_utf8(&path[prev_idx..idx - 1])?;
914 if let Ok(v) = s.parse::<u64>() {
915 let json_path = JsonPathRef::UInt64(v);
916 json_paths.push(json_path);
917 } else {
918 return Err(Error::InvalidToken);
919 }
920 }
921 } else if c == b'"' {
922 prev_idx = idx;
923 loop {
924 let c = read_char(path, &mut idx)?;
925 if c == b'\\' {
926 idx += 1;
927 } else if c == b'"' {
928 if idx < path.len() {
929 return Err(Error::InvalidToken);
930 }
931 break;
932 }
933 }
934 let s = std::str::from_utf8(&path[prev_idx..idx - 1])?;
935 let json_path = JsonPathRef::String(Cow::Borrowed(s));
936 if json_paths.is_empty() {
937 json_paths.push(json_path);
938 } else {
939 return Err(Error::InvalidToken);
940 }
941 } else {
942 if c == b':' || c == b'.' {
943 if idx == 1 {
944 return Err(Error::InvalidToken);
945 } else {
946 prev_idx = idx;
947 }
948 }
949 while idx < path.len() {
950 let c = read_char(path, &mut idx)?;
951 if c == b':' || c == b'.' || c == b'[' {
952 idx -= 1;
953 break;
954 } else if c == b'\\' {
955 idx += 1;
956 }
957 }
958 if prev_idx == idx {
959 return Err(Error::InvalidToken);
960 }
961 let s = std::str::from_utf8(&path[prev_idx..idx])?;
962 let json_path = JsonPathRef::String(Cow::Borrowed(s));
963 json_paths.push(json_path);
964 }
965 }
966 Ok(json_paths)
967}
968
969pub fn to_string(value: &[u8]) -> String {
971 if !is_jsonb(value) {
972 let json = unsafe { String::from_utf8_unchecked(value.to_vec()) };
973 return json;
974 }
975
976 let mut json = String::new();
977 container_to_string(value, &mut 0, &mut json);
978 json
979}
980
981fn container_to_string(value: &[u8], offset: &mut usize, json: &mut String) {
982 let header = read_u32(value, *offset).unwrap();
983 match header & CONTAINER_HEADER_TYPE_MASK {
984 SCALAR_CONTAINER_TAG => {
985 let mut jentry_offset = 4 + *offset;
986 let mut value_offset = 8 + *offset;
987 scalar_to_string(value, &mut jentry_offset, &mut value_offset, json);
988 }
989 ARRAY_CONTAINER_TAG => {
990 json.push('[');
991 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
992 let mut jentry_offset = 4 + *offset;
993 let mut value_offset = 4 + *offset + 4 * length;
994 for i in 0..length {
995 if i > 0 {
996 json.push(',');
997 }
998 scalar_to_string(value, &mut jentry_offset, &mut value_offset, json);
999 }
1000 json.push(']');
1001 }
1002 OBJECT_CONTAINER_TAG => {
1003 json.push('{');
1004 let length = (header & CONTAINER_HEADER_LEN_MASK) as usize;
1005 let mut jentry_offset = 4 + *offset;
1006 let mut key_offset = 4 + *offset + 8 * length;
1007 let mut keys = VecDeque::with_capacity(length);
1008 for _ in 0..length {
1009 let jentry_encoded = read_u32(value, jentry_offset).unwrap();
1010 let jentry = JEntry::decode_jentry(jentry_encoded);
1011 let key_length = jentry.length as usize;
1012 let key = unsafe {
1013 std::str::from_utf8_unchecked(&value[key_offset..key_offset + key_length])
1014 };
1015 keys.push_back(key);
1016 jentry_offset += 4;
1017 key_offset += key_length;
1018 }
1019 let mut value_offset = key_offset;
1020 for i in 0..length {
1021 if i > 0 {
1022 json.push(',');
1023 }
1024 let key = keys.pop_front().unwrap();
1025 json.push('\"');
1026 json.push_str(key);
1027 json.push('\"');
1028 json.push(':');
1029 scalar_to_string(value, &mut jentry_offset, &mut value_offset, json);
1030 }
1031 json.push('}');
1032 }
1033 _ => {}
1034 }
1035}
1036
1037fn scalar_to_string(
1038 value: &[u8],
1039 jentry_offset: &mut usize,
1040 value_offset: &mut usize,
1041 json: &mut String,
1042) {
1043 let jentry_encoded = read_u32(value, *jentry_offset).unwrap();
1044 let jentry = JEntry::decode_jentry(jentry_encoded);
1045 let length = jentry.length as usize;
1046 match jentry.type_code {
1047 NULL_TAG => json.push_str("null"),
1048 TRUE_TAG => json.push_str("true"),
1049 FALSE_TAG => json.push_str("false"),
1050 NUMBER_TAG => {
1051 let num = Number::decode(&value[*value_offset..*value_offset + length]);
1052 json.push_str(&format!("{num}"));
1053 }
1054 STRING_TAG => {
1055 let val = unsafe {
1056 std::str::from_utf8_unchecked(&value[*value_offset..*value_offset + length])
1057 };
1058 json.push('\"');
1059 json.push_str(val);
1060 json.push('\"');
1061 }
1062 CONTAINER_TAG => {
1063 container_to_string(value, value_offset, json);
1064 }
1065 _ => {}
1066 }
1067 *jentry_offset += 4;
1068 *value_offset += length;
1069}
1070
1071fn is_jsonb(value: &[u8]) -> bool {
1074 if let Some(v) = value.first() {
1075 if *v == ARRAY_PREFIX || *v == OBJECT_PREFIX || *v == SCALAR_PREFIX {
1076 return true;
1077 }
1078 }
1079 false
1080}
1081
1082fn read_char(buf: &[u8], idx: &mut usize) -> Result<u8, Error> {
1083 match buf.get(*idx) {
1084 Some(v) => {
1085 *idx += 1;
1086 Ok(*v)
1087 }
1088 None => Err(Error::InvalidEOF),
1089 }
1090}
1091
1092fn read_u32(buf: &[u8], idx: usize) -> Result<u32, Error> {
1093 let bytes: [u8; 4] = buf
1094 .get(idx..idx + 4)
1095 .ok_or(Error::InvalidEOF)?
1096 .try_into()
1097 .unwrap();
1098 Ok(u32::from_be_bytes(bytes))
1099}