1
//! JSON value types for C API (data definitions only, no serde_json dependency)
2
//!
3
//! The actual parsing/serialization lives in `azul_layout::json` which adds
4
//! serde_json-based implementations on top of these types.
5

            
6
use alloc::string::String;
7
use alloc::vec::Vec;
8
use core::fmt;
9
use azul_css::{
10
    AzString, OptionString, OptionF64, OptionBool,
11
    impl_vec, impl_vec_clone, impl_vec_debug, impl_vec_partialeq, impl_vec_mut,
12
    impl_result, impl_result_inner,
13
    impl_option, impl_option_inner,
14
};
15

            
16
// ============================================================================
17
// JSON Value Type
18
// ============================================================================
19

            
20
/// A generic JSON value that can hold any JSON type
21
#[derive(Debug, Clone, PartialEq)]
22
#[repr(C)]
23
pub struct Json {
24
    /// The type of this JSON value
25
    pub value_type: JsonType,
26
    /// Internal storage - interpretation depends on value_type
27
    /// For objects/arrays, this contains serialized data
28
    pub internal: JsonInternal,
29
}
30

            
31
/// Internal storage for JSON values.
32
///
33
/// This is a C-FFI-compatible tagged-union-via-struct: all fields always exist,
34
/// but only the field(s) corresponding to `JsonType` in the parent `Json` are
35
/// meaningful.  For compound types (`Array`, `Object`) the serialized JSON is
36
/// stored in `string_value` and re-parsed on each access — this trades repeated
37
/// parsing cost for a flat, FFI-safe layout with no interior pointers.
38
#[derive(Debug, Clone, PartialEq)]
39
#[repr(C)]
40
pub struct JsonInternal {
41
    /// For strings and serialized objects/arrays
42
    pub string_value: AzString,
43
    /// For numbers
44
    pub number_value: f64,
45
    /// For booleans
46
    pub bool_value: bool,
47
}
48

            
49
impl Default for JsonInternal {
50
    fn default() -> Self {
51
        Self {
52
            string_value: AzString::from(String::new()),
53
            number_value: 0.0,
54
            bool_value: false,
55
        }
56
    }
57
}
58

            
59
/// Type of a JSON value
60
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61
#[repr(C)]
62
pub enum JsonType {
63
    /// JSON null
64
    Null,
65
    /// JSON boolean (true/false)
66
    Bool,
67
    /// JSON number (stored as f64)
68
    Number,
69
    /// JSON string
70
    String,
71
    /// JSON array
72
    Array,
73
    /// JSON object
74
    Object,
75
}
76

            
77
/// Error when parsing JSON
78
#[derive(Debug, Clone, PartialEq)]
79
#[repr(C)]
80
pub struct JsonParseError {
81
    /// Error message
82
    pub message: AzString,
83
    /// Line number (if available)
84
    pub line: u32,
85
    /// Column number (if available)
86
    pub column: u32,
87
}
88

            
89
impl fmt::Display for JsonParseError {
90
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91
        if self.line > 0 {
92
            write!(f, "{}:{}: {}", self.line, self.column, self.message.as_str())
93
        } else {
94
            write!(f, "{}", self.message.as_str())
95
        }
96
    }
97
}
98

            
99
#[cfg(feature = "std")]
100
impl std::error::Error for JsonParseError {}
101

            
102
/// A key-value pair in a JSON object
103
#[derive(Debug, Clone, PartialEq)]
104
#[repr(C)]
105
pub struct JsonKeyValue {
106
    /// The key
107
    pub key: AzString,
108
    /// The value
109
    pub value: Json,
110
}
111

            
112
impl JsonKeyValue {
113
    /// Create a new key-value pair
114
    pub fn create(key: AzString, value: Json) -> Self {
115
        Self { key, value }
116
    }
117
}
118

            
119
// ============================================================================
120
// FFI-safe collection types
121
// ============================================================================
122

            
123
/// Option type for JsonKeyValue
124
impl_option!(JsonKeyValue, OptionJsonKeyValue, copy = false, [Debug, Clone, PartialEq]);
125

            
126
/// Vec of JsonKeyValue (FFI-safe)
127
impl_vec!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor, JsonKeyValueVecDestructorType, JsonKeyValueVecSlice, OptionJsonKeyValue);
128
impl_vec_clone!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor);
129
impl_vec_debug!(JsonKeyValue, JsonKeyValueVec);
130

            
131
impl JsonKeyValueVec {
132
    /// Creates a new, heap-allocated JsonKeyValueVec by copying elements from a C array
133
    #[inline]
134
    pub fn copy_from_array(ptr: *const JsonKeyValue, len: usize) -> Self {
135
        if ptr.is_null() || len == 0 {
136
            return Self::new();
137
        }
138
        let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
139
        Self::from_vec(slice.iter().cloned().collect())
140
    }
141
}
142

            
143
// FFI-safe JsonVec using impl_vec! macro
144
impl_vec!(Json, JsonVec, JsonVecDestructor, JsonVecDestructorType, JsonVecSlice, OptionJson);
145
impl_vec_clone!(Json, JsonVec, JsonVecDestructor);
146
impl_vec_debug!(Json, JsonVec);
147
impl_vec_partialeq!(Json, JsonVec);
148
impl_vec_mut!(Json, JsonVec);
149

            
150
impl JsonVec {
151
    /// Creates a new, heap-allocated JsonVec by copying elements from a C array
152
    #[inline]
153
    pub fn copy_from_array(ptr: *const Json, len: usize) -> Self {
154
        if ptr.is_null() || len == 0 {
155
            return Self::new();
156
        }
157
        let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
158
        Self::from_vec(slice.iter().cloned().collect())
159
    }
160
}
161

            
162
// FFI-safe Result type for JSON parsing
163
impl_result!(
164
    Json,
165
    JsonParseError,
166
    ResultJsonJsonParseError,
167
    copy = false,
168
    [Debug, Clone, PartialEq]
169
);
170

            
171
// FFI-safe Option types for JSON
172
impl_option!(Json, OptionJson, copy = false, [Clone, Debug, PartialEq]);
173
impl_option!(JsonVec, OptionJsonVec, copy = false, [Clone, Debug]);
174
impl_option!(JsonKeyValueVec, OptionJsonKeyValueVec, copy = false, [Clone, Debug]);
175

            
176
// FFI-safe Option types for JSON value extraction
177
// Note: OptionBool and OptionF64 are already exported from azul_css
178
impl_option!(i64, OptionI64, [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]);
179

            
180
// ============================================================================
181
// Helpers
182
// ============================================================================
183

            
184
/// Try to losslessly convert an `f64` to `i64`.
185
///
186
/// Returns `Some` only when `n` is an integer that fits in `i64` without
187
/// overflow.  The upper bound uses `< 2^63` (not `<= i64::MAX as f64`)
188
/// because `i64::MAX` cannot be represented exactly in `f64` — the cast
189
/// rounds up to `2^63`, which would cause overflow on `n as i64`.
190
fn f64_as_i64(n: f64) -> Option<i64> {
191
    if n.fract() == 0.0 && n >= -(2_f64.powi(63)) && n < 2_f64.powi(63) {
192
        Some(n as i64)
193
    } else {
194
        None
195
    }
196
}
197

            
198
// ============================================================================
199
// Non-serde methods on Json (pure data, no parsing)
200
// ============================================================================
201

            
202
impl Json {
203
    /// Create a null JSON value
204
    pub fn null() -> Self {
205
        Self {
206
            value_type: JsonType::Null,
207
            internal: JsonInternal::default(),
208
        }
209
    }
210

            
211
    /// Create a boolean JSON value
212
    pub fn bool(value: bool) -> Self {
213
        Self {
214
            value_type: JsonType::Bool,
215
            internal: JsonInternal {
216
                string_value: AzString::from(String::new()),
217
                number_value: 0.0,
218
                bool_value: value,
219
            },
220
        }
221
    }
222

            
223
    /// Create a number JSON value (floating-point)
224
    pub fn number(value: f64) -> Self {
225
        Self {
226
            value_type: JsonType::Number,
227
            internal: JsonInternal {
228
                string_value: AzString::from(String::new()),
229
                number_value: value,
230
                bool_value: false,
231
            },
232
        }
233
    }
234

            
235
    /// Create an integer JSON value.
236
    ///
237
    /// **Note:** the value is stored as `f64` internally, so `i64` values with
238
    /// magnitude greater than 2^53 will lose precision silently.
239
    pub fn integer(value: i64) -> Self {
240
        Self {
241
            value_type: JsonType::Number,
242
            internal: JsonInternal {
243
                string_value: AzString::from(String::new()),
244
                number_value: value as f64,
245
                bool_value: false,
246
            },
247
        }
248
    }
249

            
250
    /// Create a string JSON value
251
    pub fn string(value: impl Into<String>) -> Self {
252
        Self {
253
            value_type: JsonType::String,
254
            internal: JsonInternal {
255
                string_value: AzString::from(value.into()),
256
                number_value: 0.0,
257
                bool_value: false,
258
            },
259
        }
260
    }
261

            
262
    /// Check if this is null
263
    pub fn is_null(&self) -> bool {
264
        self.value_type == JsonType::Null
265
    }
266

            
267
    /// Check if this is a boolean
268
    pub fn is_bool(&self) -> bool {
269
        self.value_type == JsonType::Bool
270
    }
271

            
272
    /// Check if this is a number
273
    pub fn is_number(&self) -> bool {
274
        self.value_type == JsonType::Number
275
    }
276

            
277
    /// Check if this is a string
278
    pub fn is_string(&self) -> bool {
279
        self.value_type == JsonType::String
280
    }
281

            
282
    /// Check if this is an array
283
    pub fn is_array(&self) -> bool {
284
        self.value_type == JsonType::Array
285
    }
286

            
287
    /// Check if this is an object
288
    pub fn is_object(&self) -> bool {
289
        self.value_type == JsonType::Object
290
    }
291

            
292
    /// Get as boolean (returns None if not a bool)
293
    pub fn as_bool(&self) -> OptionBool {
294
        if self.value_type == JsonType::Bool {
295
            OptionBool::Some(self.internal.bool_value)
296
        } else {
297
            OptionBool::None
298
        }
299
    }
300

            
301
    /// Get as number (returns None if not a number)
302
    pub fn as_number(&self) -> OptionF64 {
303
        if self.value_type == JsonType::Number {
304
            OptionF64::Some(self.internal.number_value)
305
        } else {
306
            OptionF64::None
307
        }
308
    }
309

            
310
    /// Get as integer (returns None if not a number or not an integer)
311
    pub fn as_i64(&self) -> OptionI64 {
312
        if self.value_type == JsonType::Number {
313
            match f64_as_i64(self.internal.number_value) {
314
                Some(i) => OptionI64::Some(i),
315
                None => OptionI64::None,
316
            }
317
        } else {
318
            OptionI64::None
319
        }
320
    }
321

            
322
    /// Get as string (returns None if not a string)
323
    pub fn as_string(&self) -> OptionString {
324
        if self.value_type == JsonType::String {
325
            OptionString::Some(self.internal.string_value.clone())
326
        } else {
327
            OptionString::None
328
        }
329
    }
330

            
331
    /// Get the raw internal string value (for arrays/objects this is the serialized JSON)
332
    pub fn raw_string(&self) -> &str {
333
        self.internal.string_value.as_str()
334
    }
335
}
336

            
337
/// Note: the `Display` output is meant for human-readable / debug display.
338
/// String values are quoted but **not** JSON-escaped (no backslash escaping
339
/// of embedded quotes, newlines, etc.).  Use `to_json_string()` (requires
340
/// the `serde-json` feature) when valid JSON output is needed.
341
impl fmt::Display for Json {
342
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343
        match self.value_type {
344
            JsonType::Null => write!(f, "null"),
345
            JsonType::Bool => write!(f, "{}", self.internal.bool_value),
346
            JsonType::Number => {
347
                let num = self.internal.number_value;
348
                if let Some(i) = f64_as_i64(num) {
349
                    write!(f, "{}", i)
350
                } else {
351
                    write!(f, "{}", num)
352
                }
353
            }
354
            JsonType::String => write!(f, "\"{}\"", self.internal.string_value.as_str()),
355
            JsonType::Array | JsonType::Object => {
356
                write!(f, "{}", self.internal.string_value.as_str())
357
            }
358
        }
359
    }
360
}
361

            
362
// ============================================================================
363
// serde_json-dependent methods (gated behind "serde-json" feature)
364
// ============================================================================
365

            
366
#[cfg(feature = "serde-json")]
367
impl Json {
368
    /// Parse JSON from a string
369
    pub fn parse(s: &str) -> Result<Self, JsonParseError> {
370
        let value: serde_json::Value = serde_json::from_str(s).map_err(|e| {
371
            JsonParseError {
372
                message: AzString::from(alloc::format!("{}", e)),
373
                line: e.line() as u32,
374
                column: e.column() as u32,
375
            }
376
        })?;
377
        Ok(Self::from_serde_value(value))
378
    }
379

            
380
    /// Parse JSON from bytes (UTF-8)
381
    pub fn parse_bytes(bytes: &[u8]) -> Result<Self, JsonParseError> {
382
        let value: serde_json::Value = serde_json::from_slice(bytes).map_err(|e| {
383
            JsonParseError {
384
                message: AzString::from(alloc::format!("{}", e)),
385
                line: e.line() as u32,
386
                column: e.column() as u32,
387
            }
388
        })?;
389
        Ok(Self::from_serde_value(value))
390
    }
391

            
392
    /// Convert from serde_json::Value
393
    pub fn from_serde_value(value: serde_json::Value) -> Self {
394
        match value {
395
            serde_json::Value::Null => Self::null(),
396
            serde_json::Value::Bool(b) => Self::bool(b),
397
            serde_json::Value::Number(n) => Self::number(n.as_f64().unwrap_or(0.0)),
398
            serde_json::Value::String(s) => Self::string(s),
399
            serde_json::Value::Array(arr) => {
400
                let json_str = serde_json::to_string(&serde_json::Value::Array(arr)).unwrap_or_default();
401
                Self {
402
                    value_type: JsonType::Array,
403
                    internal: JsonInternal {
404
                        string_value: AzString::from(json_str),
405
                        number_value: 0.0,
406
                        bool_value: false,
407
                    },
408
                }
409
            }
410
            serde_json::Value::Object(obj) => {
411
                let json_str = serde_json::to_string(&serde_json::Value::Object(obj)).unwrap_or_default();
412
                Self {
413
                    value_type: JsonType::Object,
414
                    internal: JsonInternal {
415
                        string_value: AzString::from(json_str),
416
                        number_value: 0.0,
417
                        bool_value: false,
418
                    },
419
                }
420
            }
421
        }
422
    }
423

            
424
    /// Convert this Json to a serde_json::Value
425
    pub fn to_serde_value(&self) -> serde_json::Value {
426
        match self.value_type {
427
            JsonType::Null => serde_json::Value::Null,
428
            JsonType::Bool => serde_json::Value::Bool(self.internal.bool_value),
429
            JsonType::Number => {
430
                let num = self.internal.number_value;
431
                if let Some(i) = f64_as_i64(num) {
432
                    serde_json::Value::Number(serde_json::Number::from(i))
433
                } else {
434
                    serde_json::Number::from_f64(num)
435
                        .map(serde_json::Value::Number)
436
                        .unwrap_or(serde_json::Value::Null)
437
                }
438
            }
439
            JsonType::String => serde_json::Value::String(self.internal.string_value.as_str().to_string()),
440
            JsonType::Array | JsonType::Object => {
441
                serde_json::from_str(self.internal.string_value.as_str())
442
                    .unwrap_or(serde_json::Value::Null)
443
            }
444
        }
445
    }
446

            
447
    /// Create a JSON array from a vector of JSON values
448
    pub fn array(values: JsonVec) -> Self {
449
        let serde_array: Vec<serde_json::Value> = values
450
            .as_slice()
451
            .iter()
452
            .map(|j| j.to_serde_value())
453
            .collect();
454
        let json_str = serde_json::to_string(&serde_json::Value::Array(serde_array))
455
            .unwrap_or_else(|_| "[]".to_string());
456
        Self {
457
            value_type: JsonType::Array,
458
            internal: JsonInternal {
459
                string_value: AzString::from(json_str),
460
                number_value: 0.0,
461
                bool_value: false,
462
            },
463
        }
464
    }
465

            
466
    /// Create a JSON object from key-value pairs
467
    pub fn object(entries: JsonKeyValueVec) -> Self {
468
        let mut map = serde_json::Map::new();
469
        for kv in entries.as_slice() {
470
            map.insert(kv.key.as_str().to_string(), kv.value.to_serde_value());
471
        }
472
        let json_str = serde_json::to_string(&serde_json::Value::Object(map))
473
            .unwrap_or_else(|_| "{}".to_string());
474
        Self {
475
            value_type: JsonType::Object,
476
            internal: JsonInternal {
477
                string_value: AzString::from(json_str),
478
                number_value: 0.0,
479
                bool_value: false,
480
            },
481
        }
482
    }
483

            
484
    /// Get the number of elements (for arrays) or keys (for objects)
485
    pub fn len(&self) -> usize {
486
        match self.value_type {
487
            JsonType::Array => {
488
                if let Ok(serde_json::Value::Array(arr)) = serde_json::from_str(self.internal.string_value.as_str()) {
489
                    arr.len()
490
                } else {
491
                    0
492
                }
493
            }
494
            JsonType::Object => {
495
                if let Ok(serde_json::Value::Object(obj)) = serde_json::from_str(self.internal.string_value.as_str()) {
496
                    obj.len()
497
                } else {
498
                    0
499
                }
500
            }
501
            _ => 0,
502
        }
503
    }
504

            
505
    /// Check if empty (for arrays/objects)
506
    pub fn is_empty(&self) -> bool {
507
        self.len() == 0
508
    }
509

            
510
    /// Get array element by index
511
    pub fn get_index(&self, index: usize) -> Option<Json> {
512
        if self.value_type != JsonType::Array { return None; }
513
        let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
514
        if let serde_json::Value::Array(arr) = value {
515
            arr.get(index).map(|v| Self::from_serde_value(v.clone()))
516
        } else {
517
            None
518
        }
519
    }
520

            
521
    /// Get object value by key
522
    pub fn get_key(&self, key: &str) -> Option<Json> {
523
        if self.value_type != JsonType::Object { return None; }
524
        let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
525
        if let serde_json::Value::Object(obj) = value {
526
            obj.get(key).map(|v| Self::from_serde_value(v.clone()))
527
        } else {
528
            None
529
        }
530
    }
531

            
532
    /// Get all keys of an object
533
    pub fn keys(&self) -> Vec<AzString> {
534
        if self.value_type != JsonType::Object { return Vec::new(); }
535
        let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
536
            Ok(v) => v,
537
            Err(_) => return Vec::new(),
538
        };
539
        if let serde_json::Value::Object(obj) = value {
540
            obj.keys().map(|k| AzString::from(k.clone())).collect()
541
        } else {
542
            Vec::new()
543
        }
544
    }
545

            
546
    /// Convert array to Vec<Json>
547
    pub fn to_array(&self) -> Option<JsonVec> {
548
        if self.value_type != JsonType::Array { return None; }
549
        let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
550
        if let serde_json::Value::Array(arr) = value {
551
            Some(arr.into_iter().map(Self::from_serde_value).collect())
552
        } else {
553
            None
554
        }
555
    }
556

            
557
    /// Convert object to Vec<JsonKeyValue>
558
    pub fn to_object(&self) -> Option<JsonKeyValueVec> {
559
        if self.value_type != JsonType::Object { return None; }
560
        let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
561
        if let serde_json::Value::Object(obj) = value {
562
            Some(obj.into_iter().map(|(k, v)| JsonKeyValue {
563
                key: AzString::from(k),
564
                value: Self::from_serde_value(v),
565
            }).collect())
566
        } else {
567
            None
568
        }
569
    }
570

            
571
    /// Serialize to JSON string (returns AzString)
572
    pub fn to_json_string(&self) -> AzString {
573
        match self.value_type {
574
            JsonType::Null => AzString::from(alloc::string::String::from("null")),
575
            JsonType::Bool => AzString::from(if self.internal.bool_value { alloc::string::String::from("true") } else { alloc::string::String::from("false") }),
576
            JsonType::Number => {
577
                let num = self.internal.number_value;
578
                if let Some(i) = f64_as_i64(num) {
579
                    AzString::from(alloc::format!("{}", i))
580
                } else {
581
                    AzString::from(alloc::format!("{}", num))
582
                }
583
            }
584
            JsonType::String => {
585
                let escaped = serde_json::to_string(self.internal.string_value.as_str()).unwrap_or_default();
586
                AzString::from(escaped)
587
            }
588
            JsonType::Array | JsonType::Object => {
589
                self.internal.string_value.clone()
590
            }
591
        }
592
    }
593

            
594
    /// Serialize to pretty-printed JSON string
595
    pub fn to_string_pretty(&self) -> AzString {
596
        match self.value_type {
597
            JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
598
                self.to_json_string()
599
            }
600
            JsonType::Array | JsonType::Object => {
601
                if let Ok(value) = serde_json::from_str::<serde_json::Value>(self.internal.string_value.as_str()) {
602
                    AzString::from(serde_json::to_string_pretty(&value).unwrap_or_default())
603
                } else {
604
                    self.internal.string_value.clone()
605
                }
606
            }
607
        }
608
    }
609

            
610
    /// Access a nested value using a JSON Pointer (RFC 6901).
611
    pub fn jq(&self, path: &str) -> Json {
612
        match self.value_type {
613
            JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
614
                if path.is_empty() { self.clone() } else { Json::null() }
615
            }
616
            JsonType::Array | JsonType::Object => {
617
                let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
618
                    Ok(v) => v,
619
                    Err(_) => return Json::null(),
620
                };
621
                match value.pointer(path) {
622
                    Some(v) => Self::from_serde_value(v.clone()),
623
                    None => Json::null(),
624
                }
625
            }
626
        }
627
    }
628

            
629
    /// Access nested values using a JSON Pointer with wildcard support.
630
    pub fn jq_all(&self, path: &str) -> JsonVec {
631
        let result = match self.value_type {
632
            JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
633
                if path.is_empty() { vec![self.clone()] } else { vec![] }
634
            }
635
            JsonType::Array | JsonType::Object => {
636
                let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
637
                    Ok(v) => v,
638
                    Err(_) => return JsonVec::from_vec(vec![]),
639
                };
640
                Self::jq_all_recursive(&value, path)
641
            }
642
        };
643
        JsonVec::from_vec(result)
644
    }
645

            
646
    /// Recursive helper for jq_all that handles wildcards
647
    fn jq_all_recursive(value: &serde_json::Value, path: &str) -> Vec<Json> {
648
        if path.is_empty() {
649
            return vec![Self::from_serde_value(value.clone())];
650
        }
651
        if !path.starts_with('/') { return vec![]; }
652
        let rest = &path[1..];
653
        let (component, remaining) = match rest.find('/') {
654
            Some(idx) => (&rest[..idx], &rest[idx..]),
655
            None => (rest, ""),
656
        };
657
        if component == "*" {
658
            let mut results = Vec::new();
659
            match value {
660
                serde_json::Value::Array(arr) => {
661
                    for item in arr { results.extend(Self::jq_all_recursive(item, remaining)); }
662
                }
663
                serde_json::Value::Object(obj) => {
664
                    for (_key, val) in obj { results.extend(Self::jq_all_recursive(val, remaining)); }
665
                }
666
                _ => {}
667
            }
668
            results
669
        } else {
670
            match value {
671
                serde_json::Value::Array(arr) => {
672
                    if let Ok(idx) = component.parse::<usize>() {
673
                        if let Some(item) = arr.get(idx) {
674
                            return Self::jq_all_recursive(item, remaining);
675
                        }
676
                    }
677
                    vec![]
678
                }
679
                serde_json::Value::Object(obj) => {
680
                    if let Some(val) = obj.get(component) {
681
                        return Self::jq_all_recursive(val, remaining);
682
                    }
683
                    vec![]
684
                }
685
                _ => vec![],
686
            }
687
        }
688
    }
689
}