Skip to main content

lance_jsonb/functions/
scalar.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright The Lance Authors
3// SPDX-FileCopyrightText: Copyright 2023 Datafuse Labs
4// Adapted from databendlabs/jsonb at commit fba895c5ebe77ce2539e187f9c652f51cbf195c3.
5
6// This file contains functions that specifically operate on JSONB scalar values.
7
8use std::borrow::Cow;
9
10use crate::RawJsonb;
11use crate::core::JsonbItem;
12use crate::core::JsonbItemType;
13use crate::error::*;
14use crate::extension::ExtensionValue;
15use crate::number::Number;
16
17impl RawJsonb<'_> {
18    /// Checks if the JSONB value is null.
19    ///
20    /// This function determines whether the JSONB value represents a JSON `null`.
21    ///
22    /// # Arguments
23    ///
24    /// * `self` - The JSONB value.
25    ///
26    /// # Returns
27    ///
28    /// * `Ok(true)` if the value is null.
29    /// * `Ok(false)` if the value is not null.
30    /// * `Err(Error)` - If the input JSONB data is invalid.
31    ///
32    /// # Examples
33    ///
34    /// ```rust
35    /// use lance_jsonb::OwnedJsonb;
36    ///
37    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
38    /// let raw_jsonb = null_jsonb.as_raw();
39    /// assert!(raw_jsonb.is_null().unwrap());
40    ///
41    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
42    /// let raw_jsonb = obj_jsonb.as_raw();
43    /// assert!(!raw_jsonb.is_null().unwrap());
44    /// ```
45    pub fn is_null(&self) -> Result<bool> {
46        let jsonb_item_type = self.jsonb_item_type()?;
47        Ok(matches!(jsonb_item_type, JsonbItemType::Null))
48    }
49
50    /// Checks if the JSONB value is a boolean.
51    ///
52    /// This function checks if the JSONB value represents a JSON boolean (`true` or `false`).
53    ///
54    /// # Arguments
55    ///
56    /// * `self` - The JSONB value.
57    ///
58    /// # Returns
59    ///
60    /// * `Ok(true)` - If the value is a boolean (`true` or `false`).
61    /// * `Ok(false)` - If the value is not a boolean.
62    /// * `Err(Error)` - If the JSONB data is invalid.
63    ///
64    /// # Examples
65    ///
66    /// ```rust
67    /// use lance_jsonb::OwnedJsonb;
68    ///
69    /// // Boolean values
70    /// let true_jsonb = "true".parse::<OwnedJsonb>().unwrap();
71    /// let raw_true = true_jsonb.as_raw();
72    /// assert!(raw_true.is_boolean().unwrap());
73    ///
74    /// let false_jsonb = "false".parse::<OwnedJsonb>().unwrap();
75    /// let raw_false = false_jsonb.as_raw();
76    /// assert!(raw_false.is_boolean().unwrap());
77    ///
78    /// // Non-boolean values
79    /// let num_jsonb = "1".parse::<OwnedJsonb>().unwrap();
80    /// let raw_num = num_jsonb.as_raw();
81    /// assert!(!raw_num.is_boolean().unwrap());
82    ///
83    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
84    /// let raw_arr = arr_jsonb.as_raw();
85    /// assert!(!raw_arr.is_boolean().unwrap());
86    ///
87    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
88    /// let raw_obj = obj_jsonb.as_raw();
89    /// assert!(!raw_obj.is_boolean().unwrap());
90    ///
91    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
92    /// let raw_null = null_jsonb.as_raw();
93    /// assert!(!raw_null.is_boolean().unwrap());
94    ///
95    /// // Invalid JSONB
96    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
97    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
98    /// let result = invalid_raw_jsonb.is_boolean();
99    /// assert!(result.is_err());
100    /// ```
101    pub fn is_boolean(&self) -> Result<bool> {
102        let jsonb_item_type = self.jsonb_item_type()?;
103        Ok(matches!(jsonb_item_type, JsonbItemType::Boolean))
104    }
105
106    /// Extracts a boolean value from a JSONB value.
107    ///
108    /// This function attempts to extract a boolean value (`true` or `false`) from the JSONB value.
109    /// If the JSONB value is a boolean, the corresponding boolean value is returned, and return `None` otherwise.
110    ///
111    /// # Arguments
112    ///
113    /// * `self` - The JSONB value.
114    ///
115    /// # Returns
116    ///
117    /// * `Ok(Some(true))` - If the value is JSON `true`.
118    /// * `Ok(Some(false))` - If the value is JSON `false`.
119    /// * `Ok(None)` - If the value is not a boolean.
120    /// * `Err(Error)` - If the JSONB data is invalid.
121    pub(crate) fn as_bool(&self) -> Result<Option<bool>> {
122        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
123        match jsonb_item {
124            JsonbItem::Boolean(v) => Ok(Some(v)),
125            _ => Ok(None),
126        }
127    }
128
129    /// Converts a JSONB value to a boolean.
130    ///
131    /// This function attempts to convert a JSONB value to a boolean. It prioritizes extracting a boolean value directly if possible.
132    /// If the value is a string, it converts the string to lowercase and checks if it's "true" or "false". Otherwise, it returns an error.
133    ///
134    /// # Arguments
135    ///
136    /// * `self` - The JSONB value.
137    ///
138    /// # Returns
139    ///
140    /// * `Ok(true)` - If the value is JSON `true` or a string that is "true" (case-insensitive).
141    /// * `Ok(false)` - If the value is JSON `false` or a string that is "false" (case-insensitive).
142    /// * `Err(Error::InvalidCast)` - If the value cannot be converted to a boolean.
143    /// * `Err(Error)` - If the JSONB data is invalid.
144    ///
145    /// # Examples
146    ///
147    /// ```rust
148    /// use lance_jsonb::OwnedJsonb;
149    ///
150    /// // Boolean values
151    /// let true_jsonb = "true".parse::<OwnedJsonb>().unwrap();
152    /// assert!(true_jsonb.as_raw().to_bool().unwrap());
153    ///
154    /// let false_jsonb = "false".parse::<OwnedJsonb>().unwrap();
155    /// assert!(!false_jsonb.as_raw().to_bool().unwrap());
156    ///
157    /// // String representations of booleans
158    /// let true_str = r#""true""#.parse::<OwnedJsonb>().unwrap();
159    /// assert!(true_str.as_raw().to_bool().unwrap());
160    ///
161    /// let false_str = r#""false""#.parse::<OwnedJsonb>().unwrap();
162    /// assert!(!false_str.as_raw().to_bool().unwrap());
163    ///
164    /// let true_str_lowercase = r#""TRUE""#.parse::<OwnedJsonb>().unwrap();
165    /// assert!(true_str_lowercase.as_raw().to_bool().unwrap());
166    ///
167    /// // Invalid conversions
168    /// let num_jsonb = "1".parse::<OwnedJsonb>().unwrap();
169    /// let result = num_jsonb.as_raw().to_bool();
170    /// assert!(result.is_err());
171    ///
172    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
173    /// let result = arr_jsonb.as_raw().to_bool();
174    /// assert!(result.is_err());
175    ///
176    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
177    /// let result = obj_jsonb.as_raw().to_bool();
178    /// assert!(result.is_err());
179    ///
180    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
181    /// let result = null_jsonb.as_raw().to_bool();
182    /// assert!(result.is_err());
183    ///
184    /// let invalid_str = r#""maybe""#.parse::<OwnedJsonb>().unwrap();
185    /// let result = invalid_str.as_raw().to_bool();
186    /// assert!(result.is_err());
187    ///
188    /// // Invalid JSONB
189    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
190    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
191    /// let result = invalid_raw_jsonb.to_bool();
192    /// assert!(result.is_err());
193    /// ```
194    pub fn to_bool(&self) -> Result<bool> {
195        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
196        match jsonb_item {
197            JsonbItem::Boolean(v) => {
198                return Ok(v);
199            }
200            JsonbItem::String(s) => {
201                if s.eq_ignore_ascii_case("true") || s.eq_ignore_ascii_case("yes") {
202                    return Ok(true);
203                } else if s.eq_ignore_ascii_case("false") || s.eq_ignore_ascii_case("no") {
204                    return Ok(false);
205                }
206            }
207            _ => {}
208        }
209        Err(Error::InvalidCast)
210    }
211
212    /// Checks if the JSONB value is a number.
213    ///
214    /// This function checks if the JSONB value represents a JSON number.
215    ///
216    /// # Arguments
217    ///
218    /// * `self` - The JSONB value.
219    ///
220    /// # Returns
221    ///
222    /// * `Ok(true)` - If the value is a number.
223    /// * `Ok(false)` - If the value is not a number.
224    /// * `Err(Error)` - If the JSONB data is invalid.
225    ///
226    /// # Examples
227    ///
228    /// ```rust
229    /// use lance_jsonb::OwnedJsonb;
230    ///
231    /// // Number values
232    /// let num_jsonb = "123.45".parse::<OwnedJsonb>().unwrap();
233    /// let raw_num = num_jsonb.as_raw();
234    /// assert!(raw_num.is_number().unwrap());
235    ///
236    /// let num_jsonb = "123".parse::<OwnedJsonb>().unwrap();
237    /// let raw_num = num_jsonb.as_raw();
238    /// assert!(raw_num.is_number().unwrap());
239    ///
240    /// let num_jsonb = "-123.45".parse::<OwnedJsonb>().unwrap();
241    /// let raw_num = num_jsonb.as_raw();
242    /// assert!(raw_num.is_number().unwrap());
243    ///
244    /// // Non-number values
245    /// let bool_jsonb = "true".parse::<OwnedJsonb>().unwrap();
246    /// let raw_bool = bool_jsonb.as_raw();
247    /// assert!(!raw_bool.is_number().unwrap());
248    ///
249    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
250    /// let raw_str = str_jsonb.as_raw();
251    /// assert!(!raw_str.is_number().unwrap());
252    ///
253    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
254    /// let raw_arr = arr_jsonb.as_raw();
255    /// assert!(!raw_arr.is_number().unwrap());
256    ///
257    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
258    /// let raw_obj = obj_jsonb.as_raw();
259    /// assert!(!raw_obj.is_number().unwrap());
260    ///
261    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
262    /// let raw_null = null_jsonb.as_raw();
263    /// assert!(!raw_null.is_number().unwrap());
264    ///
265    /// // Invalid JSONB
266    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
267    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
268    /// let result = invalid_raw_jsonb.is_number();
269    /// assert!(result.is_err());
270    /// ```
271    pub fn is_number(&self) -> Result<bool> {
272        let jsonb_item_type = self.jsonb_item_type()?;
273        Ok(matches!(jsonb_item_type, JsonbItemType::Number))
274    }
275
276    /// Extracts a number from a JSONB value.
277    ///
278    /// This function attempts to extract a number from the JSONB value.
279    /// If the JSONB value is a number, it returns the number; otherwise, it returns `None`.
280    ///
281    /// # Arguments
282    ///
283    /// * `self` - The JSONB value.
284    ///
285    /// # Returns
286    ///
287    /// * `Ok(Some(Number))` - If the value is a number, the extracted number.
288    /// * `Ok(None)` - If the value is not a number.
289    /// * `Err(Error)` - If the JSONB data is invalid or if the number cannot be decoded.
290    ///
291    /// # Examples
292    ///
293    /// ```rust
294    /// use lance_jsonb::Number;
295    /// use lance_jsonb::OwnedJsonb;
296    /// use lance_jsonb::RawJsonb;
297    ///
298    /// // Number value
299    /// let num_jsonb = "123.45".parse::<OwnedJsonb>().unwrap();
300    /// let raw_num = num_jsonb.as_raw();
301    /// assert_eq!(raw_num.as_number().unwrap(), Some(Number::Float64(123.45)));
302    ///
303    /// let num_jsonb = "-123".parse::<OwnedJsonb>().unwrap();
304    /// let raw_num = num_jsonb.as_raw();
305    /// assert_eq!(raw_num.as_number().unwrap(), Some(Number::Int64(-123)));
306    ///
307    /// // Non-number values
308    /// let bool_jsonb = "true".parse::<OwnedJsonb>().unwrap();
309    /// let raw_bool = bool_jsonb.as_raw();
310    /// assert_eq!(raw_bool.as_number().unwrap(), None);
311    ///
312    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
313    /// let raw_str = str_jsonb.as_raw();
314    /// assert_eq!(raw_str.as_number().unwrap(), None);
315    ///
316    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
317    /// let raw_arr = arr_jsonb.as_raw();
318    /// assert_eq!(raw_arr.as_number().unwrap(), None);
319    ///
320    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
321    /// let raw_obj = obj_jsonb.as_raw();
322    /// assert_eq!(raw_obj.as_number().unwrap(), None);
323    ///
324    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
325    /// let raw_null = null_jsonb.as_raw();
326    /// assert_eq!(raw_null.as_number().unwrap(), None);
327    ///
328    /// // Invalid JSONB
329    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
330    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
331    /// let result = invalid_raw_jsonb.as_number();
332    /// assert!(result.is_err());
333    ///
334    /// // Invalid Number (corrupted data)
335    /// let corrupted_num_jsonb = OwnedJsonb::from(vec![10, 0, 0, 0, 16, 0, 0, 0, 0, 1]);
336    /// let corrupted_raw_num_jsonb = corrupted_num_jsonb.as_raw();
337    /// let result = corrupted_raw_num_jsonb.as_number();
338    /// assert!(result.is_err()); // Decodes should return Err
339    /// ```
340    pub fn as_number(&self) -> Result<Option<Number>> {
341        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
342        match jsonb_item {
343            JsonbItem::Number(num) => {
344                let value = num.as_number()?;
345                Ok(Some(value))
346            }
347            _ => Ok(None),
348        }
349    }
350
351    /// Checks whether the JSONB value is an exact `i64`.
352    ///
353    /// Decimal and floating-point numbers must already be integral.
354    ///
355    /// # Arguments
356    ///
357    /// * `self` - The JSONB value.
358    ///
359    /// # Returns
360    ///
361    /// * `Ok(true)` - If the value is an exact `i64`.
362    /// * `Ok(false)` - Otherwise.
363    /// * `Err(Error)` - If the JSONB data is invalid.
364    ///
365    /// # Examples
366    ///
367    /// ```rust
368    /// use lance_jsonb::OwnedJsonb;
369    ///
370    /// // i64 values
371    /// let i64_jsonb = "123456789012345678".parse::<OwnedJsonb>().unwrap();
372    /// let raw_i64 = i64_jsonb.as_raw();
373    /// assert!(raw_i64.is_i64().unwrap());
374    ///
375    /// let i64_jsonb = "-123456789012345678.0".parse::<OwnedJsonb>().unwrap();
376    /// let raw_i64 = i64_jsonb.as_raw();
377    /// assert!(raw_i64.is_i64().unwrap());
378    ///
379    /// let float_jsonb = "1.5e0".parse::<OwnedJsonb>().unwrap();
380    /// let raw_float = float_jsonb.as_raw();
381    /// assert!(!raw_float.is_i64().unwrap());
382    ///
383    /// // Out-of-range values
384    /// let float_jsonb = "1e100".parse::<OwnedJsonb>().unwrap();
385    /// let raw_float = float_jsonb.as_raw();
386    /// assert!(!raw_float.is_i64().unwrap());
387    ///
388    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
389    /// let raw_str = str_jsonb.as_raw();
390    /// assert!(!raw_str.is_i64().unwrap());
391    ///
392    /// // Invalid JSONB
393    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
394    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
395    /// let result = invalid_raw_jsonb.is_i64();
396    /// assert!(result.is_err());
397    /// ```
398    pub fn is_i64(&self) -> Result<bool> {
399        self.as_i64().map(|v| v.is_some())
400    }
401
402    /// Extracts an exact `i64` from a JSONB value.
403    ///
404    /// Decimal and floating-point numbers are accepted only when they already
405    /// represent an integer.
406    ///
407    /// # Arguments
408    ///
409    /// * `self` - The JSONB value.
410    ///
411    /// # Returns
412    ///
413    /// * `Ok(Some(i64))` - If the value is an exact `i64`.
414    /// * `Ok(None)` - Otherwise.
415    /// * `Err(Error)` - If the JSONB data is invalid.
416    pub(crate) fn as_i64(&self) -> Result<Option<i64>> {
417        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
418        match jsonb_item {
419            JsonbItem::Number(num) => {
420                let value = num.as_number()?;
421                Ok(value.as_i64())
422            }
423            _ => Ok(None),
424        }
425    }
426
427    /// Converts a JSONB value to `i64`.
428    ///
429    /// Numbers are rounded to the nearest integer. Booleans map to `1` and
430    /// `0`. Strings are parsed as `i64`, or as `f64` and then rounded.
431    ///
432    /// # Arguments
433    ///
434    /// * `self` - The JSONB value.
435    ///
436    /// # Returns
437    ///
438    /// * `Ok(i64)` - The converted value.
439    /// * `Err(Error::InvalidCast)` - If the value cannot be converted to an `i64`.
440    /// * `Err(Error)` - If the JSONB data is invalid.
441    ///
442    /// # Examples
443    ///
444    /// ```rust
445    /// use lance_jsonb::OwnedJsonb;
446    ///
447    /// // Integer values
448    /// let i64_jsonb = "123".parse::<OwnedJsonb>().unwrap();
449    /// assert_eq!(i64_jsonb.as_raw().to_i64().unwrap(), 123);
450    ///
451    /// let i64_jsonb = "-42".parse::<OwnedJsonb>().unwrap();
452    /// assert_eq!(i64_jsonb.as_raw().to_i64().unwrap(), -42);
453    ///
454    /// // Boolean values
455    /// let true_jsonb = "true".parse::<OwnedJsonb>().unwrap();
456    /// assert_eq!(true_jsonb.as_raw().to_i64().unwrap(), 1);
457    ///
458    /// let false_jsonb = "false".parse::<OwnedJsonb>().unwrap();
459    /// assert_eq!(false_jsonb.as_raw().to_i64().unwrap(), 0);
460    ///
461    /// // String representation of an integer
462    /// let str_jsonb = r#""123""#.parse::<OwnedJsonb>().unwrap();
463    /// assert_eq!(str_jsonb.as_raw().to_i64().unwrap(), 123);
464    ///
465    /// // Decimal and float numbers are rounded before conversion
466    /// let decimal_jsonb = "123.5".parse::<OwnedJsonb>().unwrap();
467    /// assert_eq!(decimal_jsonb.as_raw().to_i64().unwrap(), 124);
468    ///
469    /// let float_jsonb = "1.5e0".parse::<OwnedJsonb>().unwrap();
470    /// assert_eq!(float_jsonb.as_raw().to_i64().unwrap(), 2);
471    ///
472    /// let str_jsonb = r#""1.5""#.parse::<OwnedJsonb>().unwrap();
473    /// assert_eq!(str_jsonb.as_raw().to_i64().unwrap(), 2);
474    ///
475    /// // Invalid conversions
476    /// let float_jsonb = "1e100".parse::<OwnedJsonb>().unwrap();
477    /// let result = float_jsonb.as_raw().to_i64();
478    /// assert!(result.is_err());
479    ///
480    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
481    /// let result = arr_jsonb.as_raw().to_i64();
482    /// assert!(result.is_err());
483    ///
484    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
485    /// let result = obj_jsonb.as_raw().to_i64();
486    /// assert!(result.is_err());
487    ///
488    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
489    /// let result = null_jsonb.as_raw().to_i64();
490    /// assert!(result.is_err());
491    ///
492    /// let invalid_str_jsonb = r#""abc""#.parse::<OwnedJsonb>().unwrap();
493    /// let result = invalid_str_jsonb.as_raw().to_i64();
494    /// assert!(result.is_err());
495    ///
496    /// // Invalid JSONB
497    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
498    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
499    /// let result = invalid_raw_jsonb.to_i64();
500    /// assert!(result.is_err());
501    /// ```
502    pub fn to_i64(&self) -> Result<i64> {
503        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
504        match jsonb_item {
505            JsonbItem::Boolean(v) => {
506                if v {
507                    return Ok(1_i64);
508                } else {
509                    return Ok(0_i64);
510                }
511            }
512            JsonbItem::Number(num) => {
513                let value = num.as_number()?;
514                if let Some(v) = value.to_i64() {
515                    return Ok(v);
516                }
517            }
518            JsonbItem::String(s) => {
519                if let Some(v) = parse_string_to_i64(&s) {
520                    return Ok(v);
521                }
522            }
523            _ => {}
524        }
525        Err(Error::InvalidCast)
526    }
527
528    /// Converts a JSONB value to an f64 floating-point number.
529    ///
530    /// This function attempts to convert a JSONB value to an `f64` floating-point number.
531    /// It prioritizes direct conversion from a number if possible.
532    /// If the value is a boolean, it's converted to 1.0 (for `true`) or 0.0 (for `false`).
533    /// If the value is a string that can be parsed as an `f64`, that parsed value is returned.
534    /// Otherwise, an error is returned.
535    ///
536    /// # Arguments
537    ///
538    /// * `self` - The JSONB value.
539    ///
540    /// # Returns
541    ///
542    /// * `Ok(f64)` - The `f64` representation of the JSONB value.
543    /// * `Err(Error::InvalidCast)` - If the value cannot be converted to an `f64`
544    ///   (e.g., it's an array, an object, a string that is not a valid number, or a null value).
545    /// * `Err(Error)` - If the JSONB data is invalid.
546    ///
547    /// # Examples
548    ///
549    /// ```rust
550    /// use lance_jsonb::OwnedJsonb;
551    ///
552    /// // f64 values
553    /// let f64_jsonb = "123.45".parse::<OwnedJsonb>().unwrap();
554    /// assert_eq!(f64_jsonb.as_raw().to_f64().unwrap(), 123.45);
555    ///
556    /// let int_jsonb = "123".parse::<OwnedJsonb>().unwrap();
557    /// assert_eq!(int_jsonb.as_raw().to_f64().unwrap(), 123.0);
558    ///
559    /// // Boolean values
560    /// let true_jsonb = "true".parse::<OwnedJsonb>().unwrap();
561    /// assert_eq!(true_jsonb.as_raw().to_f64().unwrap(), 1.0);
562    ///
563    /// let false_jsonb = "false".parse::<OwnedJsonb>().unwrap();
564    /// assert_eq!(false_jsonb.as_raw().to_f64().unwrap(), 0.0);
565    ///
566    /// // String representation of a number
567    /// let str_jsonb = r#""123.45""#.parse::<OwnedJsonb>().unwrap();
568    /// assert_eq!(str_jsonb.as_raw().to_f64().unwrap(), 123.45);
569    ///
570    /// // Invalid conversions
571    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
572    /// let result = arr_jsonb.as_raw().to_f64();
573    /// assert!(result.is_err());
574    ///
575    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
576    /// let result = obj_jsonb.as_raw().to_f64();
577    /// assert!(result.is_err());
578    ///
579    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
580    /// let result = null_jsonb.as_raw().to_f64();
581    /// assert!(result.is_err());
582    ///
583    /// let invalid_str_jsonb = r#""abc""#.parse::<OwnedJsonb>().unwrap();
584    /// let result = invalid_str_jsonb.as_raw().to_f64();
585    /// assert!(result.is_err());
586    ///
587    /// // Invalid JSONB
588    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
589    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
590    /// let result = invalid_raw_jsonb.to_f64();
591    /// assert!(result.is_err());
592    /// ```
593    pub fn to_f64(&self) -> Result<f64> {
594        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
595        match jsonb_item {
596            JsonbItem::Boolean(v) => {
597                if v {
598                    return Ok(1_f64);
599                } else {
600                    return Ok(0_f64);
601                }
602            }
603            JsonbItem::Number(num) => {
604                let value = num.as_number()?;
605                let v = value.as_f64();
606                return Ok(v);
607            }
608            JsonbItem::String(s) => {
609                if let Ok(v) = s.parse::<f64>() {
610                    return Ok(v);
611                }
612            }
613            _ => {}
614        }
615        Err(Error::InvalidCast)
616    }
617
618    /// Checks if the JSONB value is a string.
619    ///
620    /// This function checks if the JSONB value represents a JSON string.
621    ///
622    /// # Arguments
623    ///
624    /// * `self` - The JSONB value.
625    ///
626    /// # Returns
627    ///
628    /// * `Ok(true)` - If the value is a string.
629    /// * `Ok(false)` - If the value is not a string.
630    /// * `Err(Error)` - If the JSONB data is invalid.
631    ///
632    /// # Examples
633    ///
634    /// ```rust
635    /// use lance_jsonb::OwnedJsonb;
636    ///
637    /// // String value
638    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
639    /// let raw_str = str_jsonb.as_raw();
640    /// assert!(raw_str.is_string().unwrap());
641    ///
642    /// // Non-string values
643    /// let num_jsonb = "123".parse::<OwnedJsonb>().unwrap();
644    /// let raw_num = num_jsonb.as_raw();
645    /// assert!(!raw_num.is_string().unwrap());
646    ///
647    /// let bool_jsonb = "true".parse::<OwnedJsonb>().unwrap();
648    /// let raw_bool = bool_jsonb.as_raw();
649    /// assert!(!raw_bool.is_string().unwrap());
650    ///
651    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
652    /// let raw_arr = arr_jsonb.as_raw();
653    /// assert!(!raw_arr.is_string().unwrap());
654    ///
655    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
656    /// let raw_obj = obj_jsonb.as_raw();
657    /// assert!(!raw_obj.is_string().unwrap());
658    ///
659    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
660    /// let raw_null = null_jsonb.as_raw();
661    /// assert!(!raw_null.is_string().unwrap());
662    ///
663    /// // Invalid JSONB
664    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
665    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
666    /// let result = invalid_raw_jsonb.is_string();
667    /// assert!(result.is_err());
668    /// ```
669    pub fn is_string(&self) -> Result<bool> {
670        let jsonb_item_type = self.jsonb_item_type()?;
671        Ok(matches!(jsonb_item_type, JsonbItemType::String))
672    }
673
674    /// Extracts a string from a JSONB value.
675    ///
676    /// This function attempts to extract a string from the JSONB value.
677    /// If the JSONB value is a string, it returns the string as a `Cow<'_, str>`.
678    /// Otherwise, it returns `None`.
679    ///
680    /// # Arguments
681    ///
682    /// * `self` - The JSONB value.
683    ///
684    /// # Returns
685    ///
686    /// * `Ok(Some(Cow<'_, str>))` - If the value is a string, the extracted string.
687    /// * `Ok(None)` - If the value is not a string (number, boolean, null, array, object).
688    /// * `Err(Error)` - If the JSONB data is invalid or if the string is not valid UTF-8.
689    pub(crate) fn as_str(&self) -> Result<Option<Cow<'_, str>>> {
690        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
691        match jsonb_item {
692            JsonbItem::String(s) => Ok(Some(s)),
693            _ => Ok(None),
694        }
695    }
696
697    /// Converts a JSONB value to a String.
698    ///
699    /// This function attempts to convert a JSONB value to a string representation.
700    /// It prioritizes direct conversion from strings.
701    /// Booleans are converted to "true" or "false", and numbers are converted to their string representations.
702    /// Other types (arrays, objects, null) will result in an error.
703    ///
704    /// # Arguments
705    ///
706    /// * `self` - The JSONB value.
707    ///
708    /// # Returns
709    ///
710    /// * `Ok(String)` - The string representation of the JSONB value.
711    /// * `Err(Error::InvalidCast)` - If the JSONB value cannot be converted to a string (e.g., it's an array, an object, or a null value).
712    /// * `Err(Error)` - If the JSONB data is invalid.
713    ///
714    /// # Examples
715    ///
716    /// ```rust
717    /// use lance_jsonb::OwnedJsonb;
718    ///
719    /// // String value
720    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
721    /// assert_eq!(str_jsonb.as_raw().to_str().unwrap(), "hello");
722    ///
723    /// // Number value
724    /// let num_jsonb = "123.45".parse::<OwnedJsonb>().unwrap();
725    /// assert_eq!(num_jsonb.as_raw().to_str().unwrap(), "123.45");
726    ///
727    /// // Boolean values
728    /// let true_jsonb = "true".parse::<OwnedJsonb>().unwrap();
729    /// assert_eq!(true_jsonb.as_raw().to_str().unwrap(), "true");
730    ///
731    /// let false_jsonb = "false".parse::<OwnedJsonb>().unwrap();
732    /// assert_eq!(false_jsonb.as_raw().to_str().unwrap(), "false");
733    ///
734    /// // Invalid conversions
735    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
736    /// let result = arr_jsonb.as_raw().to_str();
737    /// assert!(result.is_err());
738    ///
739    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
740    /// let result = obj_jsonb.as_raw().to_str();
741    /// assert!(result.is_err());
742    ///
743    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
744    /// let result = null_jsonb.as_raw().to_str();
745    /// assert!(result.is_err());
746    ///
747    /// // Invalid JSONB
748    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
749    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
750    /// let result = invalid_raw_jsonb.to_str();
751    /// assert!(result.is_err());
752    /// ```
753    pub fn to_str(&self) -> Result<String> {
754        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
755        match jsonb_item {
756            JsonbItem::Boolean(v) => {
757                if v {
758                    Ok("true".to_string())
759                } else {
760                    Ok("false".to_string())
761                }
762            }
763            JsonbItem::Number(num) => {
764                let value = num.as_number()?;
765                Ok(format!("{}", value))
766            }
767            JsonbItem::String(s) => Ok(s.to_string()),
768            _ => Err(Error::InvalidCast),
769        }
770    }
771
772    /// Checks if the JSONB value is an array.
773    ///
774    /// This function checks if the JSONB value represents a JSON array.
775    ///
776    /// # Arguments
777    ///
778    /// * `self` - The JSONB value.
779    ///
780    /// # Returns
781    ///
782    /// * `Ok(true)` - If the value is an array.
783    /// * `Ok(false)` - If the value is not an array.
784    /// * `Err(Error)` - If the JSONB data is invalid.
785    ///
786    /// # Examples
787    ///
788    /// ```rust
789    /// use lance_jsonb::OwnedJsonb;
790    ///
791    /// // Array value
792    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
793    /// let raw_arr = arr_jsonb.as_raw();
794    /// assert!(raw_arr.is_array().unwrap());
795    ///
796    /// // Non-array values
797    /// let num_jsonb = "123".parse::<OwnedJsonb>().unwrap();
798    /// let raw_num = num_jsonb.as_raw();
799    /// assert!(!raw_num.is_array().unwrap());
800    ///
801    /// let bool_jsonb = "true".parse::<OwnedJsonb>().unwrap();
802    /// let raw_bool = bool_jsonb.as_raw();
803    /// assert!(!raw_bool.is_array().unwrap());
804    ///
805    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
806    /// let raw_str = str_jsonb.as_raw();
807    /// assert!(!raw_str.is_array().unwrap());
808    ///
809    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
810    /// let raw_obj = obj_jsonb.as_raw();
811    /// assert!(!raw_obj.is_array().unwrap());
812    ///
813    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
814    /// let raw_null = null_jsonb.as_raw();
815    /// assert!(!raw_null.is_array().unwrap());
816    ///
817    /// // Invalid JSONB
818    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
819    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
820    /// let result = invalid_raw_jsonb.is_array();
821    /// assert!(result.is_err());
822    /// ```
823    pub fn is_array(&self) -> Result<bool> {
824        let jsonb_item_type = self.jsonb_item_type()?;
825        Ok(matches!(jsonb_item_type, JsonbItemType::Array(_)))
826    }
827
828    /// Checks if the JSONB value is an object.
829    ///
830    /// This function checks if the JSONB value represents a JSON object.
831    ///
832    /// # Arguments
833    ///
834    /// * `self` - The JSONB value.
835    ///
836    /// # Returns
837    ///
838    /// * `Ok(true)` - If the value is an object.
839    /// * `Ok(false)` - If the value is not an object.
840    /// * `Err(Error)` - If the JSONB data is invalid.
841    ///
842    /// # Examples
843    ///
844    /// ```rust
845    /// use lance_jsonb::OwnedJsonb;
846    ///
847    /// // Object value
848    /// let obj_jsonb = r#"{"a": 1}"#.parse::<OwnedJsonb>().unwrap();
849    /// let raw_obj = obj_jsonb.as_raw();
850    /// assert!(raw_obj.is_object().unwrap());
851    ///
852    /// // Non-object values
853    /// let num_jsonb = "123".parse::<OwnedJsonb>().unwrap();
854    /// let raw_num = num_jsonb.as_raw();
855    /// assert!(!raw_num.is_object().unwrap());
856    ///
857    /// let bool_jsonb = "true".parse::<OwnedJsonb>().unwrap();
858    /// let raw_bool = bool_jsonb.as_raw();
859    /// assert!(!raw_bool.is_object().unwrap());
860    ///
861    /// let str_jsonb = r#""hello""#.parse::<OwnedJsonb>().unwrap();
862    /// let raw_str = str_jsonb.as_raw();
863    /// assert!(!raw_str.is_object().unwrap());
864    ///
865    /// let arr_jsonb = "[1, 2, 3]".parse::<OwnedJsonb>().unwrap();
866    /// let raw_arr = arr_jsonb.as_raw();
867    /// assert!(!raw_arr.is_object().unwrap());
868    ///
869    /// let null_jsonb = "null".parse::<OwnedJsonb>().unwrap();
870    /// let raw_null = null_jsonb.as_raw();
871    /// assert!(!raw_null.is_object().unwrap());
872    ///
873    /// // Invalid JSONB
874    /// let invalid_jsonb = OwnedJsonb::from(vec![1, 2, 3, 4]);
875    /// let invalid_raw_jsonb = invalid_jsonb.as_raw();
876    /// let result = invalid_raw_jsonb.is_object();
877    /// assert!(result.is_err());
878    /// ```
879    pub fn is_object(&self) -> Result<bool> {
880        let jsonb_item_type = self.jsonb_item_type()?;
881        Ok(matches!(jsonb_item_type, JsonbItemType::Object(_)))
882    }
883
884    /// Extracts a extension value from a JSONB value.
885    ///
886    /// This function attempts to extract a extension value from the JSONB value.
887    ///
888    /// # Arguments
889    ///
890    /// * `self` - The JSONB value.
891    ///
892    /// # Returns
893    ///
894    /// * `Ok(Some(ExtensionValue))` - If the value is a extension value, the extracted extension value.
895    /// * `Ok(None)` - If the value is not a extension value.
896    /// * `Err(Error)` - If the JSONB data is invalid or if the extension value cannot be decoded.
897    pub(crate) fn as_extension_value(&self) -> Result<Option<ExtensionValue<'_>>> {
898        let jsonb_item = JsonbItem::from_raw_jsonb(*self)?;
899        match jsonb_item {
900            JsonbItem::Extension(ext) => {
901                let val = ext.as_extension_value()?;
902                Ok(Some(val))
903            }
904            _ => Ok(None),
905        }
906    }
907}
908
909fn parse_string_to_i64(s: &str) -> Option<i64> {
910    if let Ok(v) = s.parse::<i64>() {
911        return Some(v);
912    }
913
914    s.parse::<f64>()
915        .ok()
916        .and_then(|value| Number::Float64(value).to_i64())
917}