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

naomijub / serde_json_shape / 20495575397

24 Dec 2025 11:34PM UTC coverage: 51.955% (+0.1%) from 51.838%
20495575397

push

github

web-flow
chore: Configure Renovate (#13)

* Add renovate.json

* fix

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Julia Naomi <jnboeira@outlook.com>

102 of 190 new or added lines in 5 files covered. (53.68%)

4 existing lines in 1 file now uncovered.

691 of 1330 relevant lines covered (51.95%)

2.85 hits per line

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

29.08
/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
    /// Checks if [`JsonShape::Tuple`] is tuple containing `&[JsonShape]` in the same order and type.
33
    pub fn is_tuple_of(&self, types: &[Self]) -> bool {
1✔
34
        if let Self::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 Self::Array { r#type, .. } = self {
1✔
77
            **r#type == Self::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 Self::Array { r#type, .. } = self {
1✔
87
            matches!(**r#type, Self::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 Self::Array { r#type, .. } = self {
1✔
97
            matches!(**r#type, Self::Number { optional: true })
2✔
98
        } else {
99
            false
×
100
        }
101
    }
102
}
103

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

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

130
impl IsArrayOf<String> for Value {
131
    fn is_array_of(&self) -> bool {
1✔
132
        if let Self::Array { r#type, .. } = self {
1✔
133
            matches!(**r#type, Self::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 Self::Array { r#type, .. } = self {
1✔
143
            matches!(**r#type, Self::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 Self::Array { r#type, .. } = self {
1✔
153
            matches!(**r#type, Self::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 Self::Array { r#type, .. } = self {
1✔
163
            matches!(**r#type, Self::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 {
×
NEW
172
        if let Self::Array { r#type, .. } = self {
×
173
            matches!(
×
174
                **r#type,
×
175
                Self::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 {
×
NEW
188
        if let Self::Array { r#type, .. } = self {
×
NEW
189
            matches!(**r#type, Self::Array { optional: true, .. })
×
190
        } else {
191
            false
×
192
        }
193
    }
194
}
195

196
impl IsArrayOf<Object> for Value {
197
    fn is_array_of(&self) -> bool {
×
NEW
198
        if let Self::Array { r#type, .. } = self {
×
199
            matches!(
×
200
                **r#type,
×
201
                Self::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 {
×
NEW
214
        if let Self::Array { r#type, .. } = self {
×
NEW
215
            matches!(**r#type, Self::Object { optional: true, .. })
×
216
        } else {
217
            false
×
218
        }
219
    }
220
}
221

222
impl IsArrayOf<OneOf> for Value {
223
    fn is_array_of(&self) -> bool {
×
NEW
224
        if let Self::Array { r#type, .. } = self {
×
225
            matches!(
×
226
                **r#type,
×
227
                Self::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 {
×
NEW
240
        if let Self::Array { r#type, .. } = self {
×
NEW
241
            matches!(**r#type, Self::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 {
×
NEW
251
        if let Self::OneOf { variants, .. } = self {
×
NEW
252
            variants.contains(&Self::Null)
×
253
        } else {
254
            false
×
255
        }
256
    }
257
}
258

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

271
impl IsOneOf<String> for Value {
272
    fn is_one_of(&self) -> bool {
3✔
273
        if let Self::OneOf { variants, .. } = self {
3✔
274
            variants
275
                .iter()
276
                .any(|variant| matches!(&variant, &Self::String { optional: false }))
6✔
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 Self::OneOf { variants, .. } = self {
3✔
286
            variants
287
                .iter()
288
                .any(|variant| matches!(&variant, &Self::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 {
×
NEW
297
        if let Self::OneOf { variants, .. } = self {
×
298
            variants.iter().any(|variant| {
×
299
                matches!(
×
300
                    &variant,
×
301
                    &Self::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 {
×
NEW
315
        if let Self::OneOf { variants, .. } = self {
×
316
            variants.iter().any(|variant| {
×
317
                matches!(
×
318
                    &variant,
×
319
                    &Self::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 {
×
NEW
333
        if let Self::OneOf { variants, .. } = self {
×
334
            variants.iter().any(|variant| {
×
335
                matches!(
×
336
                    &variant,
×
337
                    &Self::OneOf {
338
                        optional: false,
339
                        ..
340
                    }
341
                )
342
            })
343
        } else {
344
            false
×
345
        }
346
    }
347
}
348

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

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

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

392
impl IsOneOf<Optional<String>> for Value {
393
    fn is_one_of(&self) -> bool {
3✔
394
        if let Self::OneOf { variants, .. } = self {
6✔
395
            variants
2✔
396
                .iter()
1✔
397
                .any(|variant| matches!(&variant, &Self::String { .. }))
3✔
398
                && variants.contains(&Self::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 Self::OneOf { variants, .. } = self {
6✔
408
            variants
1✔
409
                .iter()
1✔
410
                .any(|variant| matches!(&variant, &Self::Bool { .. }))
3✔
411
                && variants.contains(&Self::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 {
×
NEW
420
        if let Self::OneOf { variants, .. } = self {
×
421
            variants
×
422
                .iter()
×
NEW
423
                .any(|variant| matches!(&variant, &Self::Array { .. }))
×
NEW
424
                && variants.contains(&Self::Null)
×
425
        } else {
426
            false
×
427
        }
428
    }
429
}
430

431
impl IsOneOf<Optional<Object>> for Value {
432
    fn is_one_of(&self) -> bool {
×
NEW
433
        if let Self::OneOf { variants, .. } = self {
×
434
            variants
×
435
                .iter()
×
NEW
436
                .any(|variant| matches!(&variant, &Self::Object { .. }))
×
NEW
437
                && variants.contains(&Self::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 Self::OneOf { variants, optional } = self {
1✔
447
            variants
2✔
448
                .iter()
1✔
449
                .any(|variant| matches!(&variant, &Self::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 {
×
NEW
460
        if let Self::Object { content, .. } = self {
×
461
            content
462
                .iter()
NEW
463
                .any(|(k, value)| k == key && matches!(&value, &Self::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 Self::Object { content, .. } = self {
1✔
473
            content
474
                .iter()
475
                .any(|(k, value)| k == key && matches!(&value, &Self::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 Self::Object { content, .. } = self {
1✔
485
            content
486
                .iter()
487
                .any(|(k, value)| k == key && matches!(&value, &Self::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 Self::Object { content, .. } = self {
1✔
497
            content
498
                .iter()
499
                .any(|(k, value)| k == key && matches!(&value, &Self::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 {
×
NEW
508
        if let Self::Object { content, .. } = self {
×
509
            content.iter().any(|(k, value)| {
×
510
                k == key
×
511
                    && matches!(
×
512
                        &value,
×
513
                        &Self::Array {
514
                            optional: false,
515
                            ..
516
                        }
517
                    )
518
            })
519
        } else {
520
            false
×
521
        }
522
    }
523
}
524

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

544
impl IsObjectOf<Object> for Value {
545
    fn is_object_of(&self, key: &str) -> bool {
×
NEW
546
        if let Self::Object { content, .. } = self {
×
547
            content.iter().any(|(k, value)| {
×
548
                k == key
×
549
                    && matches!(
×
550
                        &value,
×
551
                        &Self::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 {
×
NEW
565
        if let Self::Object { content, .. } = self {
×
566
            content.iter().any(|(k, value)| {
×
567
                k == key
×
568
                    && matches!(
×
569
                        &value,
×
570
                        &Self::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 Self::Object { content, .. } = self {
1✔
585
            content
586
                .iter()
587
                .any(|(k, value)| k == key && matches!(&value, &Self::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 Self::Object { content, .. } = self {
1✔
597
            content
598
                .iter()
599
                .any(|(k, value)| k == key && matches!(&value, &Self::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 Self::Object { content, .. } = self {
1✔
609
            content
610
                .iter()
611
                .any(|(k, value)| k == key && matches!(&value, &Self::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 {
×
NEW
620
        if let Self::Object { content, .. } = self {
×
621
            content
622
                .iter()
NEW
623
                .any(|(k, value)| k == key && matches!(&value, &Self::Array { optional: true, .. }))
×
624
        } else {
625
            false
×
626
        }
627
    }
628
}
629

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

642
impl IsObjectOf<Optional<Object>> for Value {
643
    fn is_object_of(&self, key: &str) -> bool {
×
NEW
644
        if let Self::Object { content, .. } = self {
×
645
            content.iter().any(|(k, value)| {
×
NEW
646
                k == key && matches!(&value, &Self::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 {
×
NEW
656
        if let Self::Object { content, .. } = self {
×
657
            content
658
                .iter()
NEW
659
                .any(|(k, value)| k == key && matches!(&value, &Self::OneOf { optional: true, .. }))
×
660
        } else {
661
            false
×
662
        }
663
    }
664
}
665

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

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

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

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

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

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

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

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

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

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

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

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

805
impl IsTupleOf<Optional<OneOf>> for Value {
806
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
807
        if let Self::Tuple { elements, .. } = self {
×
NEW
808
            matches!(elements.get(i), Some(Self::OneOf { optional: true, .. }))
×
809
        } else {
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::Number { optional: false }),
851
            optional: true
852
        }));
853
        assert!(IsArrayOf::<Optional<Number>>::is_array_of(&Value::Array {
854
            r#type: Box::new(Value::Number { optional: true }),
855
            optional: false
856
        }));
857
        assert!(!IsArrayOf::<Optional<Number>>::is_array_of(&Value::Array {
858
            r#type: Box::new(Value::Bool { optional: true }),
859
            optional: false
860
        }));
861
        assert!(!IsArrayOf::<Number>::is_array_of(&Value::Array {
862
            r#type: Box::new(Value::Bool { optional: true }),
863
            optional: false
864
        }));
865
    }
866

867
    #[test]
868
    fn is_array_of_string() {
869
        assert!(IsArrayOf::<String>::is_array_of(&Value::Array {
870
            r#type: Box::new(Value::String { optional: false }),
871
            optional: false
872
        }));
873
        assert!(!IsArrayOf::<String>::is_array_of(&Value::Array {
874
            r#type: Box::new(Value::String { optional: true }),
875
            optional: false
876
        }));
877
        assert!(IsArrayOf::<Optional<String>>::is_array_of(&Value::Array {
878
            r#type: Box::new(Value::String { optional: true }),
879
            optional: false
880
        }));
881
        assert!(!IsArrayOf::<Optional<String>>::is_array_of(&Value::Array {
882
            r#type: Box::new(Value::Bool { optional: true }),
883
            optional: false
884
        }));
885
        assert!(!IsArrayOf::<String>::is_array_of(&Value::Array {
886
            r#type: Box::new(Value::String { optional: true }),
887
            optional: false
888
        }));
889
        assert!(IsArrayOf::<Optional<String>>::is_array_of(&Value::Array {
890
            r#type: Box::new(Value::String { optional: true }),
891
            optional: false
892
        }));
893
        assert!(!IsArrayOf::<Optional<String>>::is_array_of(&Value::Array {
894
            r#type: Box::new(Value::Bool { optional: true }),
895
            optional: false
896
        }));
897
        assert!(!IsArrayOf::<String>::is_array_of(&Value::Array {
898
            r#type: Box::new(Value::Bool { optional: true }),
899
            optional: false
900
        }));
901
    }
902

903
    #[test]
904
    fn is_array_of_bool() {
905
        assert!(IsArrayOf::<Boolean>::is_array_of(&Value::Array {
906
            r#type: Box::new(Value::Bool { optional: false }),
907
            optional: false
908
        }));
909
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
910
            r#type: Box::new(Value::Bool { optional: true }),
911
            optional: false
912
        }));
913
        assert!(IsArrayOf::<Optional<Boolean>>::is_array_of(&Value::Array {
914
            r#type: Box::new(Value::Bool { optional: true }),
915
            optional: false
916
        }));
917
        assert!(!IsArrayOf::<Optional<Boolean>>::is_array_of(
918
            &Value::Array {
919
                r#type: Box::new(Value::Number { optional: true }),
920
                optional: false
921
            }
922
        ));
923
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
924
            r#type: Box::new(Value::Bool { optional: true }),
925
            optional: false
926
        }));
927
        assert!(IsArrayOf::<Optional<Boolean>>::is_array_of(&Value::Array {
928
            r#type: Box::new(Value::Bool { optional: true }),
929
            optional: false
930
        }));
931
        assert!(!IsArrayOf::<Optional<Boolean>>::is_array_of(
932
            &Value::Array {
933
                r#type: Box::new(Value::Number { optional: true }),
934
                optional: false
935
            }
936
        ));
937
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
938
            r#type: Box::new(Value::String { optional: true }),
939
            optional: false
940
        }));
941
    }
942

943
    #[test]
944
    fn is_oneof_of_number() {
945
        assert!(IsOneOf::<Optional<Number>>::is_one_of(&Value::OneOf {
946
            variants: [
947
                Value::Number { optional: false },
948
                Value::Bool { optional: false },
949
                Value::String { optional: false },
950
                Value::Null
951
            ]
952
            .into(),
953
            optional: false
954
        }));
955
        assert!(IsOneOf::<Number>::is_one_of(&Value::OneOf {
956
            variants: [
957
                Value::Number { optional: false },
958
                Value::Bool { optional: false },
959
                Value::String { optional: false }
960
            ]
961
            .into(),
962
            optional: false
963
        }));
964
    }
965

966
    #[test]
967
    fn is_oneof_of_bool() {
968
        assert!(IsOneOf::<Optional<Boolean>>::is_one_of(&Value::OneOf {
969
            variants: [
970
                Value::Number { optional: true },
971
                Value::Bool { optional: true },
972
                Value::String { optional: true },
973
                Value::Null
974
            ]
975
            .into(),
976
            optional: false
977
        }));
978
        assert!(IsOneOf::<Boolean>::is_one_of(&Value::OneOf {
979
            variants: [
980
                Value::Number { optional: false },
981
                Value::Bool { optional: false },
982
                Value::String { optional: false }
983
            ]
984
            .into(),
985
            optional: false
986
        }));
987
    }
988

989
    #[test]
990
    fn is_oneof_of_string() {
991
        assert!(IsOneOf::<Optional<String>>::is_one_of(&Value::OneOf {
992
            variants: [
993
                Value::Number { optional: false },
994
                Value::Bool { optional: false },
995
                Value::String { optional: false },
996
                Value::Null
997
            ]
998
            .into(),
999
            optional: false
1000
        }));
1001
        assert!(IsOneOf::<String>::is_one_of(&Value::OneOf {
1002
            variants: [
1003
                Value::Number { optional: false },
1004
                Value::Bool { optional: false },
1005
                Value::String { optional: false }
1006
            ]
1007
            .into(),
1008
            optional: false
1009
        }));
1010
    }
1011

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

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

1031
    #[test]
1032
    fn is_object_of_string() {
1033
        assert!(IsObjectOf::<String>::is_object_of(
1034
            &Value::Object {
1035
                content: [("key".to_string(), Value::String { optional: false })].into(),
1036
                optional: false
1037
            },
1038
            "key"
1039
        ));
1040

1041
        assert!(IsObjectOf::<Optional<String>>::is_object_of(
1042
            &Value::Object {
1043
                content: [("key".to_string(), Value::String { optional: true })].into(),
1044
                optional: false
1045
            },
1046
            "key"
1047
        ));
1048
    }
1049

1050
    #[test]
1051
    fn is_object_of_bool() {
1052
        assert!(IsObjectOf::<Boolean>::is_object_of(
1053
            &Value::Object {
1054
                content: [("key".to_string(), Value::Bool { optional: false })].into(),
1055
                optional: false
1056
            },
1057
            "key"
1058
        ));
1059

1060
        assert!(IsObjectOf::<Optional<Boolean>>::is_object_of(
1061
            &Value::Object {
1062
                content: [("key".to_string(), Value::Bool { optional: true })].into(),
1063
                optional: false
1064
            },
1065
            "key"
1066
        ));
1067
    }
1068
}
1069

1070
#[cfg(test)]
1071
mod ai_tests {
1072
    use super::*;
1073

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

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

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

1109
    #[test]
1110
    fn value_is_not_oneof_optional_string() {
1111
        let value = Value::OneOf {
1112
            variants: [
1113
                Value::Bool { optional: false },
1114
                Value::Number { optional: false },
1115
                Value::Null,
1116
            ]
1117
            .into(),
1118
            optional: false,
1119
        };
1120
        assert!(!IsOneOf::<Optional<String>>::is_one_of(&value));
1121
    }
1122

1123
    #[test]
1124
    fn value_is_not_oneof_optional_oneof() {
1125
        let value = Value::OneOf {
1126
            variants: [
1127
                Value::Bool { optional: false },
1128
                Value::Number { optional: false },
1129
                Value::Null,
1130
            ]
1131
            .into(),
1132
            optional: false,
1133
        };
1134
        assert!(!IsOneOf::<Optional<OneOf>>::is_one_of(&value));
1135
    }
1136

1137
    #[test]
1138
    fn value_is_oneof_optional_oneof() {
1139
        let value = Value::OneOf {
1140
            variants: [
1141
                Value::Bool { optional: false },
1142
                Value::Number { optional: false },
1143
                Value::Null,
1144
            ]
1145
            .into(),
1146
            optional: true,
1147
        };
1148
        assert!(IsOneOf::<Optional<OneOf>>::is_one_of(&value));
1149
    }
1150

1151
    #[test]
1152
    fn value_is_arrayof_number() {
1153
        let value = Value::Array {
1154
            r#type: Box::new(Value::Number { optional: false }),
1155
            optional: false,
1156
        };
1157
        assert!(IsArrayOf::<Number>::is_array_of(&value));
1158
    }
1159

1160
    #[test]
1161
    fn value_is_not_arrayof_string() {
1162
        let value = Value::Array {
1163
            r#type: Box::new(Value::Number { optional: false }),
1164
            optional: false,
1165
        };
1166
        assert!(!IsArrayOf::<String>::is_array_of(&value));
1167
    }
1168

1169
    #[test]
1170
    fn value_is_arrayof_optional_number() {
1171
        let value = Value::Array {
1172
            r#type: Box::new(Value::Number { optional: true }),
1173
            optional: false,
1174
        };
1175
        assert!(IsArrayOf::<Optional<Number>>::is_array_of(&value));
1176
    }
1177

1178
    #[test]
1179
    fn value_is_not_arrayof_optional_string() {
1180
        let value = Value::Array {
1181
            r#type: Box::new(Value::Number { optional: true }),
1182
            optional: false,
1183
        };
1184
        assert!(!IsArrayOf::<Optional<String>>::is_array_of(&value));
1185
    }
1186

1187
    #[test]
1188
    fn value_is_objectof_number() {
1189
        let value = Value::Object {
1190
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1191
            optional: false,
1192
        };
1193
        assert!(IsObjectOf::<Number>::is_object_of(&value, "key"));
1194
    }
1195

1196
    #[test]
1197
    fn value_is_not_objectof_string() {
1198
        let value = Value::Object {
1199
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1200
            optional: false,
1201
        };
1202
        assert!(!IsObjectOf::<String>::is_object_of(&value, "key"));
1203
    }
1204

1205
    #[test]
1206
    fn test_is_tuple_of_match() {
1207
        let value = Value::Tuple {
1208
            elements: vec![
1209
                Value::Number { optional: false },
1210
                Value::String { optional: false },
1211
            ],
1212
            optional: false,
1213
        };
1214
        let types = vec![
1215
            Value::Number { optional: false },
1216
            Value::String { optional: false },
1217
        ];
1218
        assert!(value.is_tuple_of(&types));
1219
    }
1220

1221
    #[test]
1222
    fn test_is_tuple_of_match_with_optional() {
1223
        let value = Value::Tuple {
1224
            elements: vec![
1225
                Value::Number { optional: true },
1226
                Value::String { optional: false },
1227
            ],
1228
            optional: false,
1229
        };
1230
        let types = vec![
1231
            Value::Number { optional: false },
1232
            Value::String { optional: false },
1233
        ];
1234
        assert!(!value.is_tuple_of(&types));
1235
    }
1236

1237
    #[test]
1238
    fn test_is_tuple_of_mismatch() {
1239
        let value = Value::Tuple {
1240
            elements: vec![
1241
                Value::Number { optional: false },
1242
                Value::String { optional: false },
1243
            ],
1244
            optional: false,
1245
        };
1246
        let types = vec![
1247
            Value::Number { optional: false },
1248
            Value::Bool { optional: false },
1249
        ];
1250
        assert!(!value.is_tuple_of(&types));
1251
    }
1252

1253
    #[test]
1254
    fn test_is_tuple_of_length_mismatch() {
1255
        let value = Value::Tuple {
1256
            elements: vec![
1257
                Value::Number { optional: false },
1258
                Value::String { optional: false },
1259
            ],
1260
            optional: false,
1261
        };
1262
        let types = vec![Value::Number { optional: false }];
1263
        assert!(!value.is_tuple_of(&types));
1264
    }
1265

1266
    #[test]
1267
    fn test_is_tuple_of_not_tuple() {
1268
        let value = Value::Number { optional: false };
1269
        let types = vec![
1270
            Value::Number { optional: false },
1271
            Value::String { optional: false },
1272
        ];
1273
        assert!(!value.is_tuple_of(&types));
1274
    }
1275
}
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