• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

naomijub / serde_json_shape / 16128377279

07 Jul 2025 09:33PM UTC coverage: 44.651% (-1.9%) from 46.555%
16128377279

Pull #9

github

web-flow
Merge e5f3e86bc into 440d4eccd
Pull Request #9: JsonShape from serde_json::Value

27 of 113 new or added lines in 3 files covered. (23.89%)

505 of 1131 relevant lines covered (44.65%)

2.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.77
/json_shape/src/value/subtypes.rs
1
use crate::value::Value;
2

3
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `Null`.
4
pub struct Null;
5
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `Number`.
6
pub struct Number;
7
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `Boolean`.
8
pub struct Boolean;
9
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `String`.
10
pub struct String;
11
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `Array`.
12
pub struct Array;
13
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `Tuple`.
14
pub struct Tuple;
15
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `Object`.
16
pub struct Object;
17
/// Simple helper phantom struct to determine if `JsonShape` is of specific subtype `OneOf`.
18
pub struct OneOf;
19

20
/// Simple helper struct to determine if `JsonShape` is of specific optional subtype.
21
pub struct Optional<U>(std::marker::PhantomData<U>);
22

23
mod private {
24
    use crate::value::Value;
25

26
    pub trait Sealed {}
27
    impl Sealed for Value {}
28
}
29

30
impl Value {
31
    #[must_use]
32
    /// Cheecks if [`JsonShape::Tuple`] is tuple containing `&[JsonShape]` in the same order and type.
33
    pub fn is_tuple_of(&self, types: &[Value]) -> bool {
1✔
34
        if let Value::Tuple { elements, .. } = self {
2✔
35
            elements.len() == types.len() && elements.iter().zip(types.iter()).all(|(a, b)| a == b)
4✔
36
        } else {
37
            false
1✔
38
        }
39
    }
40
}
41

42
/// Checks if [`JsonShape`] is an Array of `T`
43
pub trait IsArrayOf<T>: private::Sealed {
44
    /// Checks if [`JsonShape`] is an Array of `T`
45
    /// - `value.is_array_of::<Null>()`.
46
    #[allow(dead_code)]
47
    fn is_array_of(&self) -> bool;
48
}
49

50
/// Checks if [`JsonShape`] is a Tuple of `T` at position `i`
51
pub trait IsTupleOf<T>: private::Sealed {
52
    /// Checks if [`JsonShape`] is an Tuple of `T` at position `i`
53
    /// - `value.is_tuple_of::<Null>(2)`.
54
    #[allow(dead_code)]
55
    fn is_tuple_of(&self, i: usize) -> bool;
56
}
57

58
/// Checks if [`JsonShape`] is `OneOf` containing `T`
59
pub trait IsOneOf<T>: private::Sealed {
60
    /// Checks if [`JsonShape`] is `OneOf` containing `T`
61
    /// - `value.is_one_of::<Null>()`.
62
    fn is_one_of(&self) -> bool;
63
}
64

65
/// Checks if [`JsonShape`] is `Object` containing `key: &str` and  `value: T`
66
pub trait IsObjectOf<T>: private::Sealed {
67
    /// Checks if [`JsonShape`] is `Object` containing `key: &str` and  `value: T`
68
    /// - `value.is_object_of::<Null>("key_1")`.
69
    #[allow(dead_code)]
70
    fn is_object_of(&self, key: &str) -> bool;
71
}
72

73
// ARRAY
74
impl IsArrayOf<Null> for Value {
75
    fn is_array_of(&self) -> bool {
1✔
76
        if let Value::Array { r#type, .. } = self {
1✔
77
            **r#type == Value::Null
2✔
78
        } else {
79
            false
×
80
        }
81
    }
82
}
83

84
impl IsArrayOf<Number> for Value {
85
    fn is_array_of(&self) -> bool {
1✔
86
        if let Value::Array { r#type, .. } = self {
1✔
87
            matches!(**r#type, Value::Number { optional: false })
2✔
88
        } else {
89
            false
×
90
        }
91
    }
92
}
93

94
impl IsArrayOf<Optional<Number>> for Value {
95
    fn is_array_of(&self) -> bool {
1✔
96
        if let Value::Array { r#type, .. } = self {
1✔
97
            matches!(**r#type, Value::Number { optional: true })
2✔
98
        } else {
99
            false
×
100
        }
101
    }
102
}
103

104
impl IsArrayOf<Tuple> for Value {
NEW
105
    fn is_array_of(&self) -> bool {
×
NEW
106
        if let Value::Array { r#type, .. } = self {
×
NEW
107
            matches!(
×
NEW
108
                **r#type,
×
109
                Value::Tuple {
110
                    optional: false,
111
                    ..
112
                }
113
            )
114
        } else {
NEW
115
            false
×
116
        }
117
    }
118
}
119

120
impl IsArrayOf<Optional<Tuple>> for Value {
NEW
121
    fn is_array_of(&self) -> bool {
×
NEW
122
        if let Value::Array { r#type, .. } = self {
×
NEW
123
            matches!(**r#type, Value::Tuple { optional: true, .. })
×
124
        } else {
NEW
125
            false
×
126
        }
127
    }
128
}
129

130
impl IsArrayOf<String> for Value {
131
    fn is_array_of(&self) -> bool {
1✔
132
        if let Value::Array { r#type, .. } = self {
1✔
133
            matches!(**r#type, Value::String { optional: false })
2✔
134
        } else {
135
            false
×
136
        }
137
    }
138
}
139

140
impl IsArrayOf<Optional<String>> for Value {
141
    fn is_array_of(&self) -> bool {
1✔
142
        if let Value::Array { r#type, .. } = self {
1✔
143
            matches!(**r#type, Value::String { optional: true })
2✔
144
        } else {
145
            false
×
146
        }
147
    }
148
}
149

150
impl IsArrayOf<Boolean> for Value {
151
    fn is_array_of(&self) -> bool {
1✔
152
        if let Value::Array { r#type, .. } = self {
1✔
153
            matches!(**r#type, Value::Bool { optional: false })
2✔
154
        } else {
155
            false
×
156
        }
157
    }
158
}
159

160
impl IsArrayOf<Optional<Boolean>> for Value {
161
    fn is_array_of(&self) -> bool {
1✔
162
        if let Value::Array { r#type, .. } = self {
1✔
163
            matches!(**r#type, Value::Bool { optional: true })
2✔
164
        } else {
165
            false
×
166
        }
167
    }
168
}
169

170
impl IsArrayOf<Array> for Value {
171
    fn is_array_of(&self) -> bool {
×
172
        if let Value::Array { r#type, .. } = self {
×
173
            matches!(
×
174
                **r#type,
×
175
                Value::Array {
176
                    optional: false,
177
                    ..
178
                }
179
            )
180
        } else {
181
            false
×
182
        }
183
    }
184
}
185

186
impl IsArrayOf<Optional<Array>> for Value {
187
    fn is_array_of(&self) -> bool {
×
188
        if let Value::Array { r#type, .. } = self {
×
189
            matches!(**r#type, Value::Array { optional: true, .. })
×
190
        } else {
191
            false
×
192
        }
193
    }
194
}
195

196
impl IsArrayOf<Object> for Value {
197
    fn is_array_of(&self) -> bool {
×
198
        if let Value::Array { r#type, .. } = self {
×
199
            matches!(
×
200
                **r#type,
×
201
                Value::Object {
202
                    optional: false,
203
                    ..
204
                }
205
            )
206
        } else {
207
            false
×
208
        }
209
    }
210
}
211

212
impl IsArrayOf<Optional<Object>> for Value {
213
    fn is_array_of(&self) -> bool {
×
214
        if let Value::Array { r#type, .. } = self {
×
215
            matches!(**r#type, Value::Object { optional: true, .. })
×
216
        } else {
217
            false
×
218
        }
219
    }
220
}
221

222
impl IsArrayOf<OneOf> for Value {
223
    fn is_array_of(&self) -> bool {
×
224
        if let Value::Array { r#type, .. } = self {
×
225
            matches!(
×
226
                **r#type,
×
227
                Value::OneOf {
228
                    optional: false,
229
                    ..
230
                }
231
            )
232
        } else {
233
            false
×
234
        }
235
    }
236
}
237

238
impl IsArrayOf<Optional<OneOf>> for Value {
239
    fn is_array_of(&self) -> bool {
×
240
        if let Value::Array { r#type, .. } = self {
×
241
            matches!(**r#type, Value::OneOf { optional: true, .. })
×
242
        } else {
243
            false
×
244
        }
245
    }
246
}
247

248
// OneOf
249
impl IsOneOf<Null> for Value {
250
    fn is_one_of(&self) -> bool {
×
251
        if let Value::OneOf { variants, .. } = self {
×
252
            variants.contains(&Value::Null)
×
253
        } else {
254
            false
×
255
        }
256
    }
257
}
258

259
impl IsOneOf<Number> for Value {
260
    fn is_one_of(&self) -> bool {
3✔
261
        if let Value::OneOf { variants, .. } = self {
3✔
262
            variants
263
                .iter()
264
                .any(|variant| matches!(&variant, &Value::Number { optional: false }))
3✔
265
        } else {
266
            false
3✔
267
        }
268
    }
269
}
270

271
impl IsOneOf<String> for Value {
272
    fn is_one_of(&self) -> bool {
3✔
273
        if let Value::OneOf { variants, .. } = self {
3✔
274
            variants
275
                .iter()
276
                .any(|variant| matches!(&variant, &Value::String { optional: false }))
5✔
277
        } else {
278
            false
3✔
279
        }
280
    }
281
}
282

283
impl IsOneOf<Boolean> for Value {
284
    fn is_one_of(&self) -> bool {
3✔
285
        if let Value::OneOf { variants, .. } = self {
3✔
286
            variants
287
                .iter()
288
                .any(|variant| matches!(&variant, &Value::Bool { optional: false }))
5✔
289
        } else {
290
            false
3✔
291
        }
292
    }
293
}
294

295
impl IsOneOf<Array> for Value {
296
    fn is_one_of(&self) -> bool {
×
297
        if let Value::OneOf { variants, .. } = self {
×
298
            variants.iter().any(|variant| {
×
299
                matches!(
×
300
                    &variant,
×
301
                    &Value::Array {
302
                        optional: false,
303
                        ..
304
                    }
305
                )
306
            })
307
        } else {
308
            false
×
309
        }
310
    }
311
}
312

313
impl IsOneOf<Object> for Value {
314
    fn is_one_of(&self) -> bool {
×
315
        if let Value::OneOf { variants, .. } = self {
×
316
            variants.iter().any(|variant| {
×
317
                matches!(
×
318
                    &variant,
×
319
                    &Value::Object {
320
                        optional: false,
321
                        ..
322
                    }
323
                )
324
            })
325
        } else {
326
            false
×
327
        }
328
    }
329
}
330

331
impl IsOneOf<OneOf> for Value {
332
    fn is_one_of(&self) -> bool {
×
333
        if let Value::OneOf { variants, .. } = self {
×
334
            variants.iter().any(|variant| {
×
335
                matches!(
×
336
                    &variant,
×
337
                    &Value::OneOf {
338
                        optional: false,
339
                        ..
340
                    }
341
                )
342
            })
343
        } else {
344
            false
×
345
        }
346
    }
347
}
348

349
impl IsOneOf<Tuple> for Value {
NEW
350
    fn is_one_of(&self) -> bool {
×
NEW
351
        if let Value::OneOf { variants, .. } = self {
×
NEW
352
            variants.iter().any(|variant| {
×
NEW
353
                matches!(
×
NEW
354
                    &variant,
×
355
                    &Value::Tuple {
356
                        optional: false,
357
                        ..
358
                    }
359
                )
360
            })
361
        } else {
NEW
362
            false
×
363
        }
364
    }
365
}
366

367
impl IsOneOf<Optional<Tuple>> for Value {
NEW
368
    fn is_one_of(&self) -> bool {
×
NEW
369
        if let Value::OneOf { variants, .. } = self {
×
370
            variants
371
                .iter()
NEW
372
                .any(|variant| matches!(&variant, &Value::Tuple { optional: true, .. }))
×
373
        } else {
NEW
374
            false
×
375
        }
376
    }
377
}
378

379
impl IsOneOf<Optional<Number>> for Value {
380
    fn is_one_of(&self) -> bool {
3✔
381
        if let Value::OneOf { variants, .. } = self {
6✔
382
            variants
1✔
383
                .iter()
1✔
384
                .any(|variant| matches!(&variant, &Value::Number { .. }))
3✔
385
                && variants.contains(&Value::Null)
1✔
386
        } else {
387
            false
3✔
388
        }
389
    }
390
}
391

392
impl IsOneOf<Optional<String>> for Value {
393
    fn is_one_of(&self) -> bool {
3✔
394
        if let Value::OneOf { variants, .. } = self {
6✔
395
            variants
2✔
396
                .iter()
1✔
397
                .any(|variant| matches!(&variant, &Value::String { .. }))
3✔
398
                && variants.contains(&Value::Null)
1✔
399
        } else {
400
            false
3✔
401
        }
402
    }
403
}
404

405
impl IsOneOf<Optional<Boolean>> for Value {
406
    fn is_one_of(&self) -> bool {
3✔
407
        if let Value::OneOf { variants, .. } = self {
6✔
408
            variants
1✔
409
                .iter()
1✔
410
                .any(|variant| matches!(&variant, &Value::Bool { .. }))
3✔
411
                && variants.contains(&Value::Null)
1✔
412
        } else {
413
            false
3✔
414
        }
415
    }
416
}
417

418
impl IsOneOf<Optional<Array>> for Value {
419
    fn is_one_of(&self) -> bool {
×
420
        if let Value::OneOf { variants, .. } = self {
×
421
            variants
×
422
                .iter()
×
423
                .any(|variant| matches!(&variant, &Value::Array { .. }))
×
424
                && variants.contains(&Value::Null)
×
425
        } else {
426
            false
×
427
        }
428
    }
429
}
430

431
impl IsOneOf<Optional<Object>> for Value {
432
    fn is_one_of(&self) -> bool {
×
433
        if let Value::OneOf { variants, .. } = self {
×
434
            variants
×
435
                .iter()
×
436
                .any(|variant| matches!(&variant, &Value::Object { .. }))
×
437
                && variants.contains(&Value::Null)
×
438
        } else {
439
            false
×
440
        }
441
    }
442
}
443

444
impl IsOneOf<Optional<OneOf>> for Value {
445
    fn is_one_of(&self) -> bool {
1✔
446
        if let Value::OneOf { variants, optional } = self {
2✔
447
            variants
2✔
448
                .iter()
1✔
449
                .any(|variant| matches!(&variant, &Value::OneOf { optional: true, .. }))
3✔
450
                || *optional
1✔
451
        } else {
452
            false
×
453
        }
454
    }
455
}
456

457
// Object
458
impl IsObjectOf<Null> for Value {
459
    fn is_object_of(&self, key: &str) -> bool {
×
460
        if let Value::Object { content, .. } = self {
×
461
            content
462
                .iter()
463
                .any(|(k, value)| k == key && matches!(&value, &Value::Null))
×
464
        } else {
465
            false
×
466
        }
467
    }
468
}
469

470
impl IsObjectOf<Number> for Value {
471
    fn is_object_of(&self, key: &str) -> bool {
1✔
472
        if let Value::Object { content, .. } = self {
1✔
473
            content
474
                .iter()
475
                .any(|(k, value)| k == key && matches!(&value, &Value::Number { optional: false }))
3✔
476
        } else {
477
            false
×
478
        }
479
    }
480
}
481

482
impl IsObjectOf<String> for Value {
483
    fn is_object_of(&self, key: &str) -> bool {
1✔
484
        if let Value::Object { content, .. } = self {
1✔
485
            content
486
                .iter()
487
                .any(|(k, value)| k == key && matches!(&value, &Value::String { optional: false }))
3✔
488
        } else {
489
            false
×
490
        }
491
    }
492
}
493

494
impl IsObjectOf<Boolean> for Value {
495
    fn is_object_of(&self, key: &str) -> bool {
1✔
496
        if let Value::Object { content, .. } = self {
1✔
497
            content
498
                .iter()
499
                .any(|(k, value)| k == key && matches!(&value, &Value::Bool { optional: false }))
3✔
500
        } else {
501
            false
×
502
        }
503
    }
504
}
505

506
impl IsObjectOf<Array> for Value {
507
    fn is_object_of(&self, key: &str) -> bool {
×
508
        if let Value::Object { content, .. } = self {
×
509
            content.iter().any(|(k, value)| {
×
510
                k == key
×
511
                    && matches!(
×
512
                        &value,
×
513
                        &Value::Array {
514
                            optional: false,
515
                            ..
516
                        }
517
                    )
518
            })
519
        } else {
520
            false
×
521
        }
522
    }
523
}
524

525
impl IsObjectOf<Tuple> for Value {
NEW
526
    fn is_object_of(&self, key: &str) -> bool {
×
NEW
527
        if let Value::Object { content, .. } = self {
×
NEW
528
            content.iter().any(|(k, value)| {
×
NEW
529
                k == key
×
NEW
530
                    && matches!(
×
NEW
531
                        &value,
×
532
                        &Value::Tuple {
533
                            optional: false,
534
                            ..
535
                        }
536
                    )
537
            })
538
        } else {
NEW
539
            false
×
540
        }
541
    }
542
}
543

544
impl IsObjectOf<Object> for Value {
545
    fn is_object_of(&self, key: &str) -> bool {
×
546
        if let Value::Object { content, .. } = self {
×
547
            content.iter().any(|(k, value)| {
×
548
                k == key
×
549
                    && matches!(
×
550
                        &value,
×
551
                        &Value::Object {
552
                            optional: false,
553
                            ..
554
                        }
555
                    )
556
            })
557
        } else {
558
            false
×
559
        }
560
    }
561
}
562

563
impl IsObjectOf<OneOf> for Value {
564
    fn is_object_of(&self, key: &str) -> bool {
×
565
        if let Value::Object { content, .. } = self {
×
566
            content.iter().any(|(k, value)| {
×
567
                k == key
×
568
                    && matches!(
×
569
                        &value,
×
570
                        &Value::OneOf {
571
                            optional: false,
572
                            ..
573
                        }
574
                    )
575
            })
576
        } else {
577
            false
×
578
        }
579
    }
580
}
581

582
impl IsObjectOf<Optional<Number>> for Value {
583
    fn is_object_of(&self, key: &str) -> bool {
1✔
584
        if let Value::Object { content, .. } = self {
1✔
585
            content
586
                .iter()
587
                .any(|(k, value)| k == key && matches!(&value, &Value::Number { optional: true }))
3✔
588
        } else {
589
            false
×
590
        }
591
    }
592
}
593

594
impl IsObjectOf<Optional<String>> for Value {
595
    fn is_object_of(&self, key: &str) -> bool {
1✔
596
        if let Value::Object { content, .. } = self {
1✔
597
            content
598
                .iter()
599
                .any(|(k, value)| k == key && matches!(&value, &Value::String { optional: true }))
3✔
600
        } else {
601
            false
×
602
        }
603
    }
604
}
605

606
impl IsObjectOf<Optional<Boolean>> for Value {
607
    fn is_object_of(&self, key: &str) -> bool {
1✔
608
        if let Value::Object { content, .. } = self {
1✔
609
            content
610
                .iter()
611
                .any(|(k, value)| k == key && matches!(&value, &Value::Bool { optional: true }))
3✔
612
        } else {
613
            false
×
614
        }
615
    }
616
}
617

618
impl IsObjectOf<Optional<Array>> for Value {
619
    fn is_object_of(&self, key: &str) -> bool {
×
620
        if let Value::Object { content, .. } = self {
×
621
            content.iter().any(|(k, value)| {
×
622
                k == key && matches!(&value, &Value::Array { optional: true, .. })
×
623
            })
624
        } else {
625
            false
×
626
        }
627
    }
628
}
629

630
impl IsObjectOf<Optional<Tuple>> for Value {
NEW
631
    fn is_object_of(&self, key: &str) -> bool {
×
NEW
632
        if let Value::Object { content, .. } = self {
×
NEW
633
            content.iter().any(|(k, value)| {
×
NEW
634
                k == key && matches!(&value, &Value::Tuple { optional: true, .. })
×
635
            })
636
        } else {
NEW
637
            false
×
638
        }
639
    }
640
}
641

642
impl IsObjectOf<Optional<Object>> for Value {
643
    fn is_object_of(&self, key: &str) -> bool {
×
644
        if let Value::Object { content, .. } = self {
×
645
            content.iter().any(|(k, value)| {
×
646
                k == key && matches!(&value, &Value::Object { optional: true, .. })
×
647
            })
648
        } else {
649
            false
×
650
        }
651
    }
652
}
653

654
impl IsObjectOf<Optional<OneOf>> for Value {
655
    fn is_object_of(&self, key: &str) -> bool {
×
656
        if let Value::Object { content, .. } = self {
×
657
            content.iter().any(|(k, value)| {
×
658
                k == key && matches!(&value, &Value::OneOf { optional: true, .. })
×
659
            })
660
        } else {
661
            false
×
662
        }
663
    }
664
}
665

666
// Tuple
667
impl IsTupleOf<Null> for Value {
NEW
668
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
669
        if let Value::Tuple { elements, .. } = self {
×
NEW
670
            elements.get(i).is_some_and(|v| v == &Value::Null)
×
671
        } else {
NEW
672
            false
×
673
        }
674
    }
675
}
676

677
impl IsTupleOf<Number> for Value {
NEW
678
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
679
        if let Value::Tuple { elements, .. } = self {
×
NEW
680
            matches!(elements.get(i), Some(Value::Number { optional: false }))
×
681
        } else {
NEW
682
            false
×
683
        }
684
    }
685
}
686

687
impl IsTupleOf<Optional<Number>> for Value {
NEW
688
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
689
        if let Value::Tuple { elements, .. } = self {
×
NEW
690
            matches!(elements.get(i), Some(Value::Number { optional: true }))
×
691
        } else {
NEW
692
            false
×
693
        }
694
    }
695
}
696

697
impl IsTupleOf<String> for Value {
NEW
698
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
699
        if let Value::Tuple { elements, .. } = self {
×
NEW
700
            matches!(elements.get(i), Some(Value::String { optional: false }))
×
701
        } else {
NEW
702
            false
×
703
        }
704
    }
705
}
706

707
impl IsTupleOf<Optional<String>> for Value {
NEW
708
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
709
        if let Value::Tuple { elements, .. } = self {
×
NEW
710
            matches!(elements.get(i), Some(Value::String { optional: true }))
×
711
        } else {
NEW
712
            false
×
713
        }
714
    }
715
}
716

717
impl IsTupleOf<Boolean> for Value {
NEW
718
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
719
        if let Value::Tuple { elements, .. } = self {
×
NEW
720
            matches!(elements.get(i), Some(Value::Bool { optional: false }))
×
721
        } else {
NEW
722
            false
×
723
        }
724
    }
725
}
726

727
impl IsTupleOf<Optional<Boolean>> for Value {
NEW
728
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
729
        if let Value::Tuple { elements, .. } = self {
×
NEW
730
            matches!(elements.get(i), Some(Value::Bool { optional: true }))
×
731
        } else {
NEW
732
            false
×
733
        }
734
    }
735
}
736

737
impl IsTupleOf<Array> for Value {
NEW
738
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
739
        if let Value::Tuple { elements, .. } = self {
×
NEW
740
            matches!(
×
NEW
741
                elements.get(i),
×
742
                Some(Value::Array {
743
                    optional: false,
744
                    ..
745
                })
746
            )
747
        } else {
NEW
748
            false
×
749
        }
750
    }
751
}
752

753
impl IsTupleOf<Optional<Array>> for Value {
NEW
754
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
755
        if let Value::Tuple { elements, .. } = self {
×
NEW
756
            matches!(elements.get(i), Some(Value::Array { optional: true, .. }))
×
757
        } else {
NEW
758
            false
×
759
        }
760
    }
761
}
762

763
impl IsTupleOf<Object> for Value {
NEW
764
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
765
        if let Value::Tuple { elements, .. } = self {
×
NEW
766
            matches!(
×
NEW
767
                elements.get(i),
×
768
                Some(Value::Object {
769
                    optional: false,
770
                    ..
771
                })
772
            )
773
        } else {
NEW
774
            false
×
775
        }
776
    }
777
}
778

779
impl IsTupleOf<Optional<Object>> for Value {
NEW
780
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
781
        if let Value::Tuple { elements, .. } = self {
×
NEW
782
            matches!(elements.get(i), Some(Value::Object { optional: true, .. }))
×
783
        } else {
NEW
784
            false
×
785
        }
786
    }
787
}
788

789
impl IsTupleOf<OneOf> for Value {
NEW
790
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
791
        if let Value::Tuple { elements, .. } = self {
×
NEW
792
            matches!(
×
NEW
793
                elements.get(i),
×
794
                Some(Value::OneOf {
795
                    optional: false,
796
                    ..
797
                })
798
            )
799
        } else {
NEW
800
            false
×
801
        }
802
    }
803
}
804

805
impl IsTupleOf<Optional<OneOf>> for Value {
NEW
806
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
807
        if let Value::Tuple { elements, .. } = self {
×
NEW
808
            matches!(elements.get(i), Some(Value::OneOf { optional: true, .. }))
×
809
        } else {
NEW
810
            false
×
811
        }
812
    }
813
}
814

815
#[cfg(test)]
816
mod tests {
817
    use super::*;
818

819
    #[test]
820
    fn is_array_of_null() {
821
        assert!(IsArrayOf::<Null>::is_array_of(&Value::Array {
822
            r#type: Box::new(Value::Null),
823
            optional: false
824
        }));
825
        assert!(!IsArrayOf::<Null>::is_array_of(&Value::Array {
826
            r#type: Box::new(Value::Number { optional: true }),
827
            optional: false
828
        }));
829
    }
830

831
    #[test]
832
    fn is_array_of_number() {
833
        assert!(IsArrayOf::<Number>::is_array_of(&Value::Array {
834
            r#type: Box::new(Value::Number { optional: false }),
835
            optional: false
836
        }));
837
        assert!(IsArrayOf::<Number>::is_array_of(&Value::Array {
838
            r#type: Box::new(Value::Number { optional: false }),
839
            optional: true
840
        }));
841
        assert!(IsArrayOf::<Optional<Number>>::is_array_of(&Value::Array {
842
            r#type: Box::new(Value::Number { optional: true }),
843
            optional: false
844
        }));
845
        assert!(!IsArrayOf::<Optional<Number>>::is_array_of(&Value::Array {
846
            r#type: Box::new(Value::Bool { optional: true }),
847
            optional: false
848
        }));
849
        assert!(!IsArrayOf::<Number>::is_array_of(&Value::Array {
850
            r#type: Box::new(Value::Bool { optional: true }),
851
            optional: false
852
        }));
853
    }
854

855
    #[test]
856
    fn is_array_of_string() {
857
        assert!(IsArrayOf::<String>::is_array_of(&Value::Array {
858
            r#type: Box::new(Value::String { optional: false }),
859
            optional: false
860
        }));
861
        assert!(!IsArrayOf::<String>::is_array_of(&Value::Array {
862
            r#type: Box::new(Value::String { optional: true }),
863
            optional: false
864
        }));
865
        assert!(IsArrayOf::<Optional<String>>::is_array_of(&Value::Array {
866
            r#type: Box::new(Value::String { optional: true }),
867
            optional: false
868
        }));
869
        assert!(!IsArrayOf::<Optional<String>>::is_array_of(&Value::Array {
870
            r#type: Box::new(Value::Bool { optional: true }),
871
            optional: false
872
        }));
873
        assert!(!IsArrayOf::<String>::is_array_of(&Value::Array {
874
            r#type: Box::new(Value::Bool { optional: true }),
875
            optional: false
876
        }));
877
    }
878

879
    #[test]
880
    fn is_array_of_bool() {
881
        assert!(IsArrayOf::<Boolean>::is_array_of(&Value::Array {
882
            r#type: Box::new(Value::Bool { optional: false }),
883
            optional: false
884
        }));
885
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
886
            r#type: Box::new(Value::Bool { optional: true }),
887
            optional: false
888
        }));
889
        assert!(IsArrayOf::<Optional<Boolean>>::is_array_of(&Value::Array {
890
            r#type: Box::new(Value::Bool { optional: true }),
891
            optional: false
892
        }));
893
        assert!(!IsArrayOf::<Optional<Boolean>>::is_array_of(
894
            &Value::Array {
895
                r#type: Box::new(Value::Number { optional: true }),
896
                optional: false
897
            }
898
        ));
899
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
900
            r#type: Box::new(Value::String { optional: true }),
901
            optional: false
902
        }));
903
    }
904

905
    #[test]
906
    fn is_oneof_of_number() {
907
        assert!(IsOneOf::<Optional<Number>>::is_one_of(&Value::OneOf {
908
            variants: [
909
                Value::Number { optional: false },
910
                Value::Bool { optional: false },
911
                Value::String { optional: false },
912
                Value::Null
913
            ]
914
            .into(),
915
            optional: false
916
        }));
917
        assert!(IsOneOf::<Number>::is_one_of(&Value::OneOf {
918
            variants: [
919
                Value::Number { optional: false },
920
                Value::Bool { optional: false },
921
                Value::String { optional: false }
922
            ]
923
            .into(),
924
            optional: false
925
        }));
926
    }
927

928
    #[test]
929
    fn is_oneof_of_bool() {
930
        assert!(IsOneOf::<Optional<Boolean>>::is_one_of(&Value::OneOf {
931
            variants: [
932
                Value::Number { optional: true },
933
                Value::Bool { optional: true },
934
                Value::String { optional: true },
935
                Value::Null
936
            ]
937
            .into(),
938
            optional: false
939
        }));
940
        assert!(IsOneOf::<Boolean>::is_one_of(&Value::OneOf {
941
            variants: [
942
                Value::Number { optional: false },
943
                Value::Bool { optional: false },
944
                Value::String { optional: false }
945
            ]
946
            .into(),
947
            optional: false
948
        }));
949
    }
950

951
    #[test]
952
    fn is_oneof_of_string() {
953
        assert!(IsOneOf::<Optional<String>>::is_one_of(&Value::OneOf {
954
            variants: [
955
                Value::Number { optional: false },
956
                Value::Bool { optional: false },
957
                Value::String { optional: false },
958
                Value::Null
959
            ]
960
            .into(),
961
            optional: false
962
        }));
963
        assert!(IsOneOf::<String>::is_one_of(&Value::OneOf {
964
            variants: [
965
                Value::Number { optional: false },
966
                Value::Bool { optional: false },
967
                Value::String { optional: false }
968
            ]
969
            .into(),
970
            optional: false
971
        }));
972
    }
973

974
    #[test]
975
    fn is_object_of_number() {
976
        assert!(IsObjectOf::<Number>::is_object_of(
977
            &Value::Object {
978
                content: [("key".to_string(), Value::Number { optional: false })].into(),
979
                optional: false
980
            },
981
            "key"
982
        ));
983

984
        assert!(IsObjectOf::<Optional<Number>>::is_object_of(
985
            &Value::Object {
986
                content: [("key".to_string(), Value::Number { optional: true })].into(),
987
                optional: false
988
            },
989
            "key"
990
        ));
991
    }
992

993
    #[test]
994
    fn is_object_of_string() {
995
        assert!(IsObjectOf::<String>::is_object_of(
996
            &Value::Object {
997
                content: [("key".to_string(), Value::String { optional: false })].into(),
998
                optional: false
999
            },
1000
            "key"
1001
        ));
1002

1003
        assert!(IsObjectOf::<Optional<String>>::is_object_of(
1004
            &Value::Object {
1005
                content: [("key".to_string(), Value::String { optional: true })].into(),
1006
                optional: false
1007
            },
1008
            "key"
1009
        ));
1010
    }
1011

1012
    #[test]
1013
    fn is_object_of_bool() {
1014
        assert!(IsObjectOf::<Boolean>::is_object_of(
1015
            &Value::Object {
1016
                content: [("key".to_string(), Value::Bool { optional: false })].into(),
1017
                optional: false
1018
            },
1019
            "key"
1020
        ));
1021

1022
        assert!(IsObjectOf::<Optional<Boolean>>::is_object_of(
1023
            &Value::Object {
1024
                content: [("key".to_string(), Value::Bool { optional: true })].into(),
1025
                optional: false
1026
            },
1027
            "key"
1028
        ));
1029
    }
1030
}
1031

1032
#[cfg(test)]
1033
mod ai_tests {
1034
    use super::*;
1035

1036
    #[test]
1037
    fn value_is_oneof_number() {
1038
        let value = Value::OneOf {
1039
            variants: [
1040
                Value::Number { optional: false },
1041
                Value::String { optional: false },
1042
            ]
1043
            .into(),
1044
            optional: false,
1045
        };
1046
        assert!(IsOneOf::<Number>::is_one_of(&value));
1047
    }
1048

1049
    #[test]
1050
    fn value_is_not_oneof_string() {
1051
        let value = Value::OneOf {
1052
            variants: [
1053
                Value::Number { optional: false },
1054
                Value::Bool { optional: false },
1055
            ]
1056
            .into(),
1057
            optional: false,
1058
        };
1059
        assert!(!IsOneOf::<String>::is_one_of(&value));
1060
    }
1061

1062
    #[test]
1063
    fn value_is_oneof_optional_number() {
1064
        let value = Value::OneOf {
1065
            variants: [Value::Null, Value::Number { optional: false }].into(),
1066
            optional: false,
1067
        };
1068
        assert!(IsOneOf::<Optional<Number>>::is_one_of(&value));
1069
    }
1070

1071
    #[test]
1072
    fn value_is_not_oneof_optional_string() {
1073
        let value = Value::OneOf {
1074
            variants: [
1075
                Value::Bool { optional: false },
1076
                Value::Number { optional: false },
1077
                Value::Null,
1078
            ]
1079
            .into(),
1080
            optional: false,
1081
        };
1082
        assert!(!IsOneOf::<Optional<String>>::is_one_of(&value));
1083
    }
1084

1085
    #[test]
1086
    fn value_is_not_oneof_optional_oneof() {
1087
        let value = Value::OneOf {
1088
            variants: [
1089
                Value::Bool { optional: false },
1090
                Value::Number { optional: false },
1091
                Value::Null,
1092
            ]
1093
            .into(),
1094
            optional: false,
1095
        };
1096
        assert!(!IsOneOf::<Optional<OneOf>>::is_one_of(&value));
1097
    }
1098

1099
    #[test]
1100
    fn value_is_oneof_optional_oneof() {
1101
        let value = Value::OneOf {
1102
            variants: [
1103
                Value::Bool { optional: false },
1104
                Value::Number { optional: false },
1105
                Value::Null,
1106
            ]
1107
            .into(),
1108
            optional: true,
1109
        };
1110
        assert!(IsOneOf::<Optional<OneOf>>::is_one_of(&value));
1111
    }
1112

1113
    #[test]
1114
    fn value_is_arrayof_number() {
1115
        let value = Value::Array {
1116
            r#type: Box::new(Value::Number { optional: false }),
1117
            optional: false,
1118
        };
1119
        assert!(IsArrayOf::<Number>::is_array_of(&value));
1120
    }
1121

1122
    #[test]
1123
    fn value_is_not_arrayof_string() {
1124
        let value = Value::Array {
1125
            r#type: Box::new(Value::Number { optional: false }),
1126
            optional: false,
1127
        };
1128
        assert!(!IsArrayOf::<String>::is_array_of(&value));
1129
    }
1130

1131
    #[test]
1132
    fn value_is_arrayof_optional_number() {
1133
        let value = Value::Array {
1134
            r#type: Box::new(Value::Number { optional: true }),
1135
            optional: false,
1136
        };
1137
        assert!(IsArrayOf::<Optional<Number>>::is_array_of(&value));
1138
    }
1139

1140
    #[test]
1141
    fn value_is_not_arrayof_optional_string() {
1142
        let value = Value::Array {
1143
            r#type: Box::new(Value::Number { optional: true }),
1144
            optional: false,
1145
        };
1146
        assert!(!IsArrayOf::<Optional<String>>::is_array_of(&value));
1147
    }
1148

1149
    #[test]
1150
    fn value_is_objectof_number() {
1151
        let value = Value::Object {
1152
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1153
            optional: false,
1154
        };
1155
        assert!(IsObjectOf::<Number>::is_object_of(&value, "key"));
1156
    }
1157

1158
    #[test]
1159
    fn value_is_not_objectof_string() {
1160
        let value = Value::Object {
1161
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1162
            optional: false,
1163
        };
1164
        assert!(!IsObjectOf::<String>::is_object_of(&value, "key"));
1165
    }
1166

1167
    #[test]
1168
    fn test_is_tuple_of_match() {
1169
        let value = Value::Tuple {
1170
            elements: vec![
1171
                Value::Number { optional: false },
1172
                Value::String { optional: false },
1173
            ],
1174
            optional: false,
1175
        };
1176
        let types = vec![
1177
            Value::Number { optional: false },
1178
            Value::String { optional: false },
1179
        ];
1180
        assert!(value.is_tuple_of(&types));
1181
    }
1182

1183
    #[test]
1184
    fn test_is_tuple_of_match_with_optional() {
1185
        let value = Value::Tuple {
1186
            elements: vec![
1187
                Value::Number { optional: true },
1188
                Value::String { optional: false },
1189
            ],
1190
            optional: false,
1191
        };
1192
        let types = vec![
1193
            Value::Number { optional: false },
1194
            Value::String { optional: false },
1195
        ];
1196
        assert!(!value.is_tuple_of(&types));
1197
    }
1198

1199
    #[test]
1200
    fn test_is_tuple_of_mismatch() {
1201
        let value = Value::Tuple {
1202
            elements: vec![
1203
                Value::Number { optional: false },
1204
                Value::String { optional: false },
1205
            ],
1206
            optional: false,
1207
        };
1208
        let types = vec![
1209
            Value::Number { optional: false },
1210
            Value::Bool { optional: false },
1211
        ];
1212
        assert!(!value.is_tuple_of(&types));
1213
    }
1214

1215
    #[test]
1216
    fn test_is_tuple_of_length_mismatch() {
1217
        let value = Value::Tuple {
1218
            elements: vec![
1219
                Value::Number { optional: false },
1220
                Value::String { optional: false },
1221
            ],
1222
            optional: false,
1223
        };
1224
        let types = vec![Value::Number { optional: false }];
1225
        assert!(!value.is_tuple_of(&types));
1226
    }
1227

1228
    #[test]
1229
    fn test_is_tuple_of_not_tuple() {
1230
        let value = Value::Number { optional: false };
1231
        let types = vec![
1232
            Value::Number { optional: false },
1233
            Value::String { optional: false },
1234
        ];
1235
        assert!(!value.is_tuple_of(&types));
1236
    }
1237
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc