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

naomijub / serde_json_shape / 16107730782

07 Jul 2025 04:37AM UTC coverage: 43.148% (-3.4%) from 46.555%
16107730782

Pull #9

github

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

13 of 113 new or added lines in 3 files covered. (11.5%)

488 of 1131 relevant lines covered (43.15%)

2.34 hits per line

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

27.72
/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 })
1✔
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 {
×
162
        if let Value::Array { r#type, .. } = self {
×
163
            matches!(**r#type, Value::Bool { optional: true })
×
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 }))
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 Value::OneOf { variants, .. } = self {
3✔
286
            variants
287
                .iter()
288
                .any(|variant| matches!(&variant, &Value::Bool { optional: false }))
3✔
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
3✔
396
                .iter()
1✔
397
                .any(|variant| matches!(&variant, &Value::String { .. }))
4✔
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 {
1✔
447
            variants
2✔
448
                .iter()
1✔
449
                .any(|variant| matches!(&variant, &Value::OneOf { optional: true, .. }))
4✔
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::Bool { optional: true }),
839
            optional: false
840
        }));
841
    }
842

843
    #[test]
844
    fn is_array_of_string() {
845
        assert!(IsArrayOf::<String>::is_array_of(&Value::Array {
846
            r#type: Box::new(Value::String { optional: false }),
847
            optional: false
848
        }));
849
        assert!(!IsArrayOf::<String>::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_bool() {
857
        assert!(IsArrayOf::<Boolean>::is_array_of(&Value::Array {
858
            r#type: Box::new(Value::Bool { optional: false }),
859
            optional: false
860
        }));
861
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
862
            r#type: Box::new(Value::String { optional: true }),
863
            optional: false
864
        }));
865
    }
866

867
    #[test]
868
    fn is_oneof_of_number() {
869
        assert!(IsOneOf::<Optional<Number>>::is_one_of(&Value::OneOf {
870
            variants: [
871
                Value::Number { optional: false },
872
                Value::Bool { optional: false },
873
                Value::String { optional: false },
874
                Value::Null
875
            ]
876
            .into(),
877
            optional: false
878
        }));
879
        assert!(IsOneOf::<Number>::is_one_of(&Value::OneOf {
880
            variants: [
881
                Value::Number { optional: false },
882
                Value::Bool { optional: false },
883
                Value::String { optional: false }
884
            ]
885
            .into(),
886
            optional: false
887
        }));
888
    }
889

890
    #[test]
891
    fn is_oneof_of_bool() {
892
        assert!(IsOneOf::<Optional<Boolean>>::is_one_of(&Value::OneOf {
893
            variants: [
894
                Value::Number { optional: true },
895
                Value::Bool { optional: true },
896
                Value::String { optional: true },
897
                Value::Null
898
            ]
899
            .into(),
900
            optional: false
901
        }));
902
        assert!(IsOneOf::<Boolean>::is_one_of(&Value::OneOf {
903
            variants: [
904
                Value::Number { optional: false },
905
                Value::Bool { optional: false },
906
                Value::String { optional: false }
907
            ]
908
            .into(),
909
            optional: false
910
        }));
911
    }
912

913
    #[test]
914
    fn is_oneof_of_string() {
915
        assert!(IsOneOf::<Optional<String>>::is_one_of(&Value::OneOf {
916
            variants: [
917
                Value::Number { optional: false },
918
                Value::Bool { optional: false },
919
                Value::String { optional: false },
920
                Value::Null
921
            ]
922
            .into(),
923
            optional: false
924
        }));
925
        assert!(IsOneOf::<String>::is_one_of(&Value::OneOf {
926
            variants: [
927
                Value::Number { optional: false },
928
                Value::Bool { optional: false },
929
                Value::String { optional: false }
930
            ]
931
            .into(),
932
            optional: false
933
        }));
934
    }
935

936
    #[test]
937
    fn is_object_of_number() {
938
        assert!(IsObjectOf::<Number>::is_object_of(
939
            &Value::Object {
940
                content: [("key".to_string(), Value::Number { optional: false })].into(),
941
                optional: false
942
            },
943
            "key"
944
        ));
945

946
        assert!(IsObjectOf::<Optional<Number>>::is_object_of(
947
            &Value::Object {
948
                content: [("key".to_string(), Value::Number { optional: true })].into(),
949
                optional: false
950
            },
951
            "key"
952
        ));
953
    }
954

955
    #[test]
956
    fn is_object_of_string() {
957
        assert!(IsObjectOf::<String>::is_object_of(
958
            &Value::Object {
959
                content: [("key".to_string(), Value::String { optional: false })].into(),
960
                optional: false
961
            },
962
            "key"
963
        ));
964

965
        assert!(IsObjectOf::<Optional<String>>::is_object_of(
966
            &Value::Object {
967
                content: [("key".to_string(), Value::String { optional: true })].into(),
968
                optional: false
969
            },
970
            "key"
971
        ));
972
    }
973

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

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

994
#[cfg(test)]
995
mod ai_tests {
996
    use super::*;
997

998
    #[test]
999
    fn value_is_oneof_number() {
1000
        let value = Value::OneOf {
1001
            variants: [
1002
                Value::Number { optional: false },
1003
                Value::String { optional: false },
1004
            ]
1005
            .into(),
1006
            optional: false,
1007
        };
1008
        assert!(IsOneOf::<Number>::is_one_of(&value));
1009
    }
1010

1011
    #[test]
1012
    fn value_is_not_oneof_string() {
1013
        let value = Value::OneOf {
1014
            variants: [
1015
                Value::Number { optional: false },
1016
                Value::Bool { optional: false },
1017
            ]
1018
            .into(),
1019
            optional: false,
1020
        };
1021
        assert!(!IsOneOf::<String>::is_one_of(&value));
1022
    }
1023

1024
    #[test]
1025
    fn value_is_oneof_optional_number() {
1026
        let value = Value::OneOf {
1027
            variants: [Value::Null, Value::Number { optional: false }].into(),
1028
            optional: false,
1029
        };
1030
        assert!(IsOneOf::<Optional<Number>>::is_one_of(&value));
1031
    }
1032

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

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

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

1075
    #[test]
1076
    fn value_is_arrayof_number() {
1077
        let value = Value::Array {
1078
            r#type: Box::new(Value::Number { optional: false }),
1079
            optional: false,
1080
        };
1081
        assert!(IsArrayOf::<Number>::is_array_of(&value));
1082
    }
1083

1084
    #[test]
1085
    fn value_is_not_arrayof_string() {
1086
        let value = Value::Array {
1087
            r#type: Box::new(Value::Number { optional: false }),
1088
            optional: false,
1089
        };
1090
        assert!(!IsArrayOf::<String>::is_array_of(&value));
1091
    }
1092

1093
    #[test]
1094
    fn value_is_arrayof_optional_number() {
1095
        let value = Value::Array {
1096
            r#type: Box::new(Value::Number { optional: true }),
1097
            optional: false,
1098
        };
1099
        assert!(IsArrayOf::<Optional<Number>>::is_array_of(&value));
1100
    }
1101

1102
    #[test]
1103
    fn value_is_not_arrayof_optional_string() {
1104
        let value = Value::Array {
1105
            r#type: Box::new(Value::Number { optional: true }),
1106
            optional: false,
1107
        };
1108
        assert!(!IsArrayOf::<Optional<String>>::is_array_of(&value));
1109
    }
1110

1111
    #[test]
1112
    fn value_is_objectof_number() {
1113
        let value = Value::Object {
1114
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1115
            optional: false,
1116
        };
1117
        assert!(IsObjectOf::<Number>::is_object_of(&value, "key"));
1118
    }
1119

1120
    #[test]
1121
    fn value_is_not_objectof_string() {
1122
        let value = Value::Object {
1123
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1124
            optional: false,
1125
        };
1126
        assert!(!IsObjectOf::<String>::is_object_of(&value, "key"));
1127
    }
1128

1129
    #[test]
1130
    fn test_is_tuple_of_match() {
1131
        let value = Value::Tuple {
1132
            elements: vec![
1133
                Value::Number { optional: false },
1134
                Value::String { optional: false },
1135
            ],
1136
            optional: false,
1137
        };
1138
        let types = vec![
1139
            Value::Number { optional: false },
1140
            Value::String { optional: false },
1141
        ];
1142
        assert!(value.is_tuple_of(&types));
1143
    }
1144

1145
    #[test]
1146
    fn test_is_tuple_of_match_with_optional() {
1147
        let value = Value::Tuple {
1148
            elements: vec![
1149
                Value::Number { optional: true },
1150
                Value::String { optional: false },
1151
            ],
1152
            optional: false,
1153
        };
1154
        let types = vec![
1155
            Value::Number { optional: false },
1156
            Value::String { optional: false },
1157
        ];
1158
        assert!(!value.is_tuple_of(&types));
1159
    }
1160

1161
    #[test]
1162
    fn test_is_tuple_of_mismatch() {
1163
        let value = Value::Tuple {
1164
            elements: vec![
1165
                Value::Number { optional: false },
1166
                Value::String { optional: false },
1167
            ],
1168
            optional: false,
1169
        };
1170
        let types = vec![
1171
            Value::Number { optional: false },
1172
            Value::Bool { optional: false },
1173
        ];
1174
        assert!(!value.is_tuple_of(&types));
1175
    }
1176

1177
    #[test]
1178
    fn test_is_tuple_of_length_mismatch() {
1179
        let value = Value::Tuple {
1180
            elements: vec![
1181
                Value::Number { optional: false },
1182
                Value::String { optional: false },
1183
            ],
1184
            optional: false,
1185
        };
1186
        let types = vec![Value::Number { optional: false }];
1187
        assert!(!value.is_tuple_of(&types));
1188
    }
1189

1190
    #[test]
1191
    fn test_is_tuple_of_not_tuple() {
1192
        let value = Value::Number { optional: false };
1193
        let types = vec![
1194
            Value::Number { optional: false },
1195
            Value::String { optional: false },
1196
        ];
1197
        assert!(!value.is_tuple_of(&types));
1198
    }
1199
}
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