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

naomijub / serde_json_shape / 16107706673

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

Pull #9

github

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

16 of 112 new or added lines in 3 files covered. (14.29%)

488 of 1131 relevant lines covered (43.15%)

2.36 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)
5✔
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!(**r#type, Value::Tuple { optional: false, .. })
×
108
        } else {
NEW
109
            false
×
110
        }
111
    }
112
}
113

114
impl IsArrayOf<Optional<Tuple>> for Value {
NEW
115
    fn is_array_of(&self) -> bool {
×
NEW
116
        if let Value::Array { r#type, .. } = self {
×
NEW
117
            matches!(**r#type, Value::Tuple { optional: true, .. })
×
118
        } else {
NEW
119
            false
×
120
        }
121
    }
122
}
123

124
impl IsArrayOf<String> for Value {
125
    fn is_array_of(&self) -> bool {
1✔
126
        if let Value::Array { r#type, .. } = self {
1✔
127
            matches!(**r#type, Value::String { optional: false })
2✔
128
        } else {
NEW
129
            false
×
130
        }
131
    }
132
}
133

134
impl IsArrayOf<Optional<String>> for Value {
135
    fn is_array_of(&self) -> bool {
1✔
136
        if let Value::Array { r#type, .. } = self {
1✔
137
            matches!(**r#type, Value::String { optional: true })
1✔
138
        } else {
139
            false
×
140
        }
141
    }
142
}
143

144
impl IsArrayOf<Boolean> for Value {
145
    fn is_array_of(&self) -> bool {
1✔
146
        if let Value::Array { r#type, .. } = self {
1✔
147
            matches!(**r#type, Value::Bool { optional: false })
2✔
148
        } else {
149
            false
×
150
        }
151
    }
152
}
153

154
impl IsArrayOf<Optional<Boolean>> for Value {
155
    fn is_array_of(&self) -> bool {
×
156
        if let Value::Array { r#type, .. } = self {
×
157
            matches!(**r#type, Value::Bool { optional: true })
×
158
        } else {
159
            false
×
160
        }
161
    }
162
}
163

164
impl IsArrayOf<Array> for Value {
165
    fn is_array_of(&self) -> bool {
×
166
        if let Value::Array { r#type, .. } = self {
×
167
            matches!(
×
168
                **r#type,
×
169
                Value::Array {
170
                    optional: false,
171
                    ..
172
                }
173
            )
174
        } else {
175
            false
×
176
        }
177
    }
178
}
179

180
impl IsArrayOf<Optional<Array>> for Value {
181
    fn is_array_of(&self) -> bool {
×
182
        if let Value::Array { r#type, .. } = self {
×
183
            matches!(**r#type, Value::Array { optional: true, .. })
×
184
        } else {
185
            false
×
186
        }
187
    }
188
}
189

190
impl IsArrayOf<Object> for Value {
191
    fn is_array_of(&self) -> bool {
×
192
        if let Value::Array { r#type, .. } = self {
×
193
            matches!(
×
194
                **r#type,
×
195
                Value::Object {
196
                    optional: false,
197
                    ..
198
                }
199
            )
200
        } else {
201
            false
×
202
        }
203
    }
204
}
205

206
impl IsArrayOf<Optional<Object>> for Value {
207
    fn is_array_of(&self) -> bool {
×
208
        if let Value::Array { r#type, .. } = self {
×
209
            matches!(**r#type, Value::Object { optional: true, .. })
×
210
        } else {
211
            false
×
212
        }
213
    }
214
}
215

216
impl IsArrayOf<OneOf> for Value {
217
    fn is_array_of(&self) -> bool {
×
218
        if let Value::Array { r#type, .. } = self {
×
219
            matches!(
×
220
                **r#type,
×
221
                Value::OneOf {
222
                    optional: false,
223
                    ..
224
                }
225
            )
226
        } else {
227
            false
×
228
        }
229
    }
230
}
231

232
impl IsArrayOf<Optional<OneOf>> for Value {
233
    fn is_array_of(&self) -> bool {
×
234
        if let Value::Array { r#type, .. } = self {
×
235
            matches!(**r#type, Value::OneOf { optional: true, .. })
×
236
        } else {
237
            false
×
238
        }
239
    }
240
}
241

242
// OneOf
243
impl IsOneOf<Null> for Value {
244
    fn is_one_of(&self) -> bool {
×
245
        if let Value::OneOf { variants, .. } = self {
×
246
            variants.contains(&Value::Null)
×
247
        } else {
248
            false
×
249
        }
250
    }
251
}
252

253
impl IsOneOf<Number> for Value {
254
    fn is_one_of(&self) -> bool {
3✔
255
        if let Value::OneOf { variants, .. } = self {
3✔
256
            variants
257
                .iter()
258
                .any(|variant| matches!(&variant, &Value::Number { optional: false }))
3✔
259
        } else {
260
            false
3✔
261
        }
262
    }
263
}
264

265
impl IsOneOf<String> for Value {
266
    fn is_one_of(&self) -> bool {
3✔
267
        if let Value::OneOf { variants, .. } = self {
3✔
268
            variants
269
                .iter()
270
                .any(|variant| matches!(&variant, &Value::String { optional: false }))
5✔
271
        } else {
272
            false
3✔
273
        }
274
    }
275
}
276

277
impl IsOneOf<Boolean> for Value {
278
    fn is_one_of(&self) -> bool {
3✔
279
        if let Value::OneOf { variants, .. } = self {
3✔
280
            variants
281
                .iter()
282
                .any(|variant| matches!(&variant, &Value::Bool { optional: false }))
5✔
283
        } else {
284
            false
3✔
285
        }
286
    }
287
}
288

289
impl IsOneOf<Array> for Value {
290
    fn is_one_of(&self) -> bool {
×
291
        if let Value::OneOf { variants, .. } = self {
×
292
            variants.iter().any(|variant| {
×
293
                matches!(
×
294
                    &variant,
×
295
                    &Value::Array {
296
                        optional: false,
297
                        ..
298
                    }
299
                )
300
            })
301
        } else {
302
            false
×
303
        }
304
    }
305
}
306

307
impl IsOneOf<Object> for Value {
308
    fn is_one_of(&self) -> bool {
×
309
        if let Value::OneOf { variants, .. } = self {
×
310
            variants.iter().any(|variant| {
×
311
                matches!(
×
312
                    &variant,
×
313
                    &Value::Object {
314
                        optional: false,
315
                        ..
316
                    }
317
                )
318
            })
319
        } else {
320
            false
×
321
        }
322
    }
323
}
324

325
impl IsOneOf<OneOf> for Value {
326
    fn is_one_of(&self) -> bool {
×
327
        if let Value::OneOf { variants, .. } = self {
×
328
            variants.iter().any(|variant| {
×
329
                matches!(
×
330
                    &variant,
×
331
                    &Value::OneOf {
332
                        optional: false,
333
                        ..
334
                    }
335
                )
336
            })
337
        } else {
338
            false
×
339
        }
340
    }
341
}
342

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

361
impl IsOneOf<Optional<Tuple>> for Value {
NEW
362
    fn is_one_of(&self) -> bool {
×
NEW
363
        if let Value::OneOf { variants, .. } = self {
×
NEW
364
            variants.iter().any(|variant| {
×
NEW
365
                matches!(
×
NEW
366
                    &variant,
×
367
                    &Value::Tuple {
368
                        optional: true,
369
                        ..
370
                    }
371
                )
372
            })
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
3✔
448
                .iter()
1✔
449
                .any(|variant| matches!(&variant, &Value::OneOf { optional: true, .. }))
6✔
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), Some(
×
742
                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), Some(
×
768
                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!(elements.get(i), Some(Value::OneOf { optional: false, ..}))
×
793
        } else {
NEW
794
            false
×
795
        }
796
    }
797
}
798

799
impl IsTupleOf<Optional<OneOf>> for Value {
NEW
800
    fn is_tuple_of(&self, i: usize) -> bool {
×
NEW
801
        if let Value::Tuple { elements , .. } = self {
×
NEW
802
            matches!(elements.get(i), Some(Value::OneOf { optional: true, .. }))
×
803
        } else {
NEW
804
            false
×
805
        }
806
    }
807
}
808

809
#[cfg(test)]
810
mod tests {
811
    use super::*;
812

813
    #[test]
814
    fn is_array_of_null() {
815
        assert!(IsArrayOf::<Null>::is_array_of(&Value::Array {
816
            r#type: Box::new(Value::Null),
817
            optional: false
818
        }));
819
        assert!(!IsArrayOf::<Null>::is_array_of(&Value::Array {
820
            r#type: Box::new(Value::Number { optional: true }),
821
            optional: false
822
        }));
823
    }
824

825
    #[test]
826
    fn is_array_of_number() {
827
        assert!(IsArrayOf::<Number>::is_array_of(&Value::Array {
828
            r#type: Box::new(Value::Number { optional: false }),
829
            optional: false
830
        }));
831
        assert!(!IsArrayOf::<Number>::is_array_of(&Value::Array {
832
            r#type: Box::new(Value::Bool { optional: true }),
833
            optional: false
834
        }));
835
    }
836

837
    #[test]
838
    fn is_array_of_string() {
839
        assert!(IsArrayOf::<String>::is_array_of(&Value::Array {
840
            r#type: Box::new(Value::String { optional: false }),
841
            optional: false
842
        }));
843
        assert!(!IsArrayOf::<String>::is_array_of(&Value::Array {
844
            r#type: Box::new(Value::Bool { optional: true }),
845
            optional: false
846
        }));
847
    }
848

849
    #[test]
850
    fn is_array_of_bool() {
851
        assert!(IsArrayOf::<Boolean>::is_array_of(&Value::Array {
852
            r#type: Box::new(Value::Bool { optional: false }),
853
            optional: false
854
        }));
855
        assert!(!IsArrayOf::<Boolean>::is_array_of(&Value::Array {
856
            r#type: Box::new(Value::String { optional: true }),
857
            optional: false
858
        }));
859
    }
860

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

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

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

930
    #[test]
931
    fn is_object_of_number() {
932
        assert!(IsObjectOf::<Number>::is_object_of(
933
            &Value::Object {
934
                content: [("key".to_string(), Value::Number { optional: false })].into(),
935
                optional: false
936
            },
937
            "key"
938
        ));
939

940
        assert!(IsObjectOf::<Optional<Number>>::is_object_of(
941
            &Value::Object {
942
                content: [("key".to_string(), Value::Number { optional: true })].into(),
943
                optional: false
944
            },
945
            "key"
946
        ));
947
    }
948

949
    #[test]
950
    fn is_object_of_string() {
951
        assert!(IsObjectOf::<String>::is_object_of(
952
            &Value::Object {
953
                content: [("key".to_string(), Value::String { optional: false })].into(),
954
                optional: false
955
            },
956
            "key"
957
        ));
958

959
        assert!(IsObjectOf::<Optional<String>>::is_object_of(
960
            &Value::Object {
961
                content: [("key".to_string(), Value::String { optional: true })].into(),
962
                optional: false
963
            },
964
            "key"
965
        ));
966
    }
967

968
    #[test]
969
    fn is_object_of_bool() {
970
        assert!(IsObjectOf::<Boolean>::is_object_of(
971
            &Value::Object {
972
                content: [("key".to_string(), Value::Bool { optional: false })].into(),
973
                optional: false
974
            },
975
            "key"
976
        ));
977

978
        assert!(IsObjectOf::<Optional<Boolean>>::is_object_of(
979
            &Value::Object {
980
                content: [("key".to_string(), Value::Bool { optional: true })].into(),
981
                optional: false
982
            },
983
            "key"
984
        ));
985
    }
986
}
987

988
#[cfg(test)]
989
mod ai_tests {
990
    use super::*;
991

992
    #[test]
993
    fn value_is_oneof_number() {
994
        let value = Value::OneOf {
995
            variants: [
996
                Value::Number { optional: false },
997
                Value::String { optional: false },
998
            ]
999
            .into(),
1000
            optional: false,
1001
        };
1002
        assert!(IsOneOf::<Number>::is_one_of(&value));
1003
    }
1004

1005
    #[test]
1006
    fn value_is_not_oneof_string() {
1007
        let value = Value::OneOf {
1008
            variants: [
1009
                Value::Number { optional: false },
1010
                Value::Bool { optional: false },
1011
            ]
1012
            .into(),
1013
            optional: false,
1014
        };
1015
        assert!(!IsOneOf::<String>::is_one_of(&value));
1016
    }
1017

1018
    #[test]
1019
    fn value_is_oneof_optional_number() {
1020
        let value = Value::OneOf {
1021
            variants: [Value::Null, Value::Number { optional: false }].into(),
1022
            optional: false,
1023
        };
1024
        assert!(IsOneOf::<Optional<Number>>::is_one_of(&value));
1025
    }
1026

1027
    #[test]
1028
    fn value_is_not_oneof_optional_string() {
1029
        let value = Value::OneOf {
1030
            variants: [
1031
                Value::Bool { optional: false },
1032
                Value::Number { optional: false },
1033
                Value::Null,
1034
            ]
1035
            .into(),
1036
            optional: false,
1037
        };
1038
        assert!(!IsOneOf::<Optional<String>>::is_one_of(&value));
1039
    }
1040

1041
    #[test]
1042
    fn value_is_not_oneof_optional_oneof() {
1043
        let value = Value::OneOf {
1044
            variants: [
1045
                Value::Bool { optional: false },
1046
                Value::Number { optional: false },
1047
                Value::Null,
1048
            ]
1049
            .into(),
1050
            optional: false,
1051
        };
1052
        assert!(!IsOneOf::<Optional<OneOf>>::is_one_of(&value));
1053
    }
1054

1055
    #[test]
1056
    fn value_is_oneof_optional_oneof() {
1057
        let value = Value::OneOf {
1058
            variants: [
1059
                Value::Bool { optional: false },
1060
                Value::Number { optional: false },
1061
                Value::Null,
1062
            ]
1063
            .into(),
1064
            optional: true,
1065
        };
1066
        assert!(IsOneOf::<Optional<OneOf>>::is_one_of(&value));
1067
    }
1068

1069
    #[test]
1070
    fn value_is_arrayof_number() {
1071
        let value = Value::Array {
1072
            r#type: Box::new(Value::Number { optional: false }),
1073
            optional: false,
1074
        };
1075
        assert!(IsArrayOf::<Number>::is_array_of(&value));
1076
    }
1077

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

1087
    #[test]
1088
    fn value_is_arrayof_optional_number() {
1089
        let value = Value::Array {
1090
            r#type: Box::new(Value::Number { optional: true }),
1091
            optional: false,
1092
        };
1093
        assert!(IsArrayOf::<Optional<Number>>::is_array_of(&value));
1094
    }
1095

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

1105
    #[test]
1106
    fn value_is_objectof_number() {
1107
        let value = Value::Object {
1108
            content: [("key".to_string(), Value::Number { optional: false })].into(),
1109
            optional: false,
1110
        };
1111
        assert!(IsObjectOf::<Number>::is_object_of(&value, "key"));
1112
    }
1113

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

1123
    #[test]
1124
    fn test_is_tuple_of_match() {
1125
        let value = Value::Tuple {
1126
            elements: vec![
1127
                Value::Number { optional: false },
1128
                Value::String { optional: false },
1129
            ],
1130
            optional: false,
1131
        };
1132
        let types = vec![
1133
            Value::Number { optional: false },
1134
            Value::String { optional: false },
1135
        ];
1136
        assert!(value.is_tuple_of(&types));
1137
    }
1138

1139
    #[test]
1140
    fn test_is_tuple_of_match_with_optional() {
1141
        let value = Value::Tuple {
1142
            elements: vec![
1143
                Value::Number { optional: true },
1144
                Value::String { optional: false },
1145
            ],
1146
            optional: false,
1147
        };
1148
        let types = vec![
1149
            Value::Number { optional: false },
1150
            Value::String { optional: false },
1151
        ];
1152
        assert!(!value.is_tuple_of(&types));
1153
    }
1154

1155
    #[test]
1156
    fn test_is_tuple_of_mismatch() {
1157
        let value = Value::Tuple {
1158
            elements: vec![
1159
                Value::Number { optional: false },
1160
                Value::String { optional: false },
1161
            ],
1162
            optional: false,
1163
        };
1164
        let types = vec![
1165
            Value::Number { optional: false },
1166
            Value::Bool { optional: false },
1167
        ];
1168
        assert!(!value.is_tuple_of(&types));
1169
    }
1170

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

1184
    #[test]
1185
    fn test_is_tuple_of_not_tuple() {
1186
        let value = Value::Number { optional: false };
1187
        let types = vec![
1188
            Value::Number { optional: false },
1189
            Value::String { optional: false },
1190
        ];
1191
        assert!(!value.is_tuple_of(&types));
1192
    }
1193
}
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