jsonschema_rs 0.48.5 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/src/canonical.rs CHANGED
@@ -1,5 +1,7 @@
1
1
  use jsonschema::{
2
- canonical::{CanonicalSchema, CanonicalView, CanonicalizationError},
2
+ canonical::{
3
+ CanonicalSchema, CanonicalView, CanonicalizationError, ContainsView as CoreContainsView,
4
+ },
3
5
  JsonType,
4
6
  };
5
7
  use magnus::{
@@ -130,18 +132,50 @@ impl RbCanonicalSchema {
130
132
  min_length: view.min_length,
131
133
  max_length: view.max_length,
132
134
  patterns: view.patterns,
135
+ formats: view.formats,
136
+ content_media_types: view.content_media_types,
137
+ content_encodings: view.content_encodings,
138
+ })
139
+ .as_value(),
140
+ CanonicalView::Number(view) => ruby
141
+ .obj_wrap(NumberView {
142
+ minimum: view.minimum,
143
+ exclusive_minimum: view.exclusive_minimum,
144
+ maximum: view.maximum,
145
+ exclusive_maximum: view.exclusive_maximum,
146
+ multiple_of: view.multiple_of,
133
147
  })
134
148
  .as_value(),
135
149
  CanonicalView::Integer(view) => ruby
136
150
  .obj_wrap(IntegerView {
137
151
  minimum: view.minimum,
138
152
  maximum: view.maximum,
153
+ multiple_of: view.multiple_of,
154
+ })
155
+ .as_value(),
156
+ CanonicalView::Array(view) => ruby
157
+ .obj_wrap(ArrayView {
158
+ min_items: view.min_items,
159
+ max_items: view.max_items,
160
+ unique_items: view.unique_items,
161
+ prefix_items: view.prefix_items,
162
+ items: view.items,
163
+ contains: view.contains,
164
+ })
165
+ .as_value(),
166
+ CanonicalView::Object(view) => ruby
167
+ .obj_wrap(ObjectView {
168
+ min_properties: view.min_properties,
169
+ max_properties: view.max_properties,
170
+ required: view.required,
171
+ property_names: view.property_names,
172
+ properties: view.properties,
173
+ pattern_properties: view.pattern_properties,
174
+ additional_properties: view.additional_properties,
139
175
  })
140
176
  .as_value(),
141
177
  CanonicalView::AnyOf(branches) => ruby.obj_wrap(AnyOfView { branches }).as_value(),
142
178
  CanonicalView::Raw(schema) => ruby.obj_wrap(RawView { schema }).as_value(),
143
- // TODO(canonical): new `CanonicalView` variants need view classes here.
144
- other => unreachable!("unsupported canonical view: {other:?}"),
145
179
  }
146
180
  }
147
181
 
@@ -289,13 +323,36 @@ fn bound_to_ruby(ruby: &Ruby, bound: Option<&serde_json::Number>) -> Result<Valu
289
323
  }
290
324
  }
291
325
 
292
- /// A string value within a length window, matching every pattern.
326
+ fn divisors_to_ruby(ruby: &Ruby, divisors: &[serde_json::Number]) -> Result<Value, Error> {
327
+ let array = ruby.ary_new_capa(divisors.len());
328
+ for divisor in divisors {
329
+ array.push(value_to_ruby(
330
+ ruby,
331
+ &serde_json::Value::Number(divisor.clone()),
332
+ )?)?;
333
+ }
334
+ Ok(array.as_value())
335
+ }
336
+
337
+ fn strings_to_ruby(ruby: &Ruby, values: &[String]) -> Result<Value, Error> {
338
+ let array = ruby.ary_new_capa(values.len());
339
+ for value in values {
340
+ array.push(ruby.str_new(value).as_value())?;
341
+ }
342
+ Ok(array.as_value())
343
+ }
344
+
345
+ /// A string value within a length window, matching every pattern, format, media type, and
346
+ /// encoding.
293
347
  #[derive(magnus::TypedData)]
294
348
  #[magnus(class = "JSONSchema::Canonical::StringView", free_immediately)]
295
349
  pub struct StringView {
296
350
  min_length: Option<serde_json::Number>,
297
351
  max_length: Option<serde_json::Number>,
298
352
  patterns: Vec<String>,
353
+ formats: Vec<String>,
354
+ content_media_types: Vec<String>,
355
+ content_encodings: Vec<String>,
299
356
  }
300
357
 
301
358
  impl DataTypeFunctions for StringView {}
@@ -310,19 +367,30 @@ impl StringView {
310
367
  }
311
368
 
312
369
  fn patterns(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
313
- let array = ruby.ary_new_capa(rb_self.patterns.len());
314
- for pattern in &rb_self.patterns {
315
- array.push(ruby.str_new(pattern).as_value())?;
316
- }
317
- Ok(array.as_value())
370
+ strings_to_ruby(ruby, &rb_self.patterns)
371
+ }
372
+
373
+ fn formats(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
374
+ strings_to_ruby(ruby, &rb_self.formats)
375
+ }
376
+
377
+ fn content_media_types(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
378
+ strings_to_ruby(ruby, &rb_self.content_media_types)
379
+ }
380
+
381
+ fn content_encodings(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
382
+ strings_to_ruby(ruby, &rb_self.content_encodings)
318
383
  }
319
384
 
320
385
  fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
321
386
  Ok(format!(
322
- "#<JSONSchema::Canonical::StringView min_length={} max_length={} patterns={}>",
387
+ "#<JSONSchema::Canonical::StringView min_length={} max_length={} patterns={} formats={} content_media_types={} content_encodings={}>",
323
388
  Self::min_length(ruby, rb_self)?.inspect(),
324
389
  Self::max_length(ruby, rb_self)?.inspect(),
325
- Self::patterns(ruby, rb_self)?.inspect()
390
+ Self::patterns(ruby, rb_self)?.inspect(),
391
+ Self::formats(ruby, rb_self)?.inspect(),
392
+ Self::content_media_types(ruby, rb_self)?.inspect(),
393
+ Self::content_encodings(ruby, rb_self)?.inspect()
326
394
  ))
327
395
  }
328
396
 
@@ -331,16 +399,91 @@ impl StringView {
331
399
  hash.aset(ruby.sym_new("min_length"), Self::min_length(ruby, rb_self)?)?;
332
400
  hash.aset(ruby.sym_new("max_length"), Self::max_length(ruby, rb_self)?)?;
333
401
  hash.aset(ruby.sym_new("patterns"), Self::patterns(ruby, rb_self)?)?;
402
+ hash.aset(ruby.sym_new("formats"), Self::formats(ruby, rb_self)?)?;
403
+ hash.aset(
404
+ ruby.sym_new("content_media_types"),
405
+ Self::content_media_types(ruby, rb_self)?,
406
+ )?;
407
+ hash.aset(
408
+ ruby.sym_new("content_encodings"),
409
+ Self::content_encodings(ruby, rb_self)?,
410
+ )?;
411
+ Ok(hash)
412
+ }
413
+ }
414
+
415
+ /// A number value within a real interval.
416
+ #[derive(magnus::TypedData)]
417
+ #[magnus(class = "JSONSchema::Canonical::NumberView", free_immediately)]
418
+ pub struct NumberView {
419
+ minimum: Option<serde_json::Number>,
420
+ exclusive_minimum: bool,
421
+ maximum: Option<serde_json::Number>,
422
+ exclusive_maximum: bool,
423
+ multiple_of: Vec<serde_json::Number>,
424
+ }
425
+
426
+ impl DataTypeFunctions for NumberView {}
427
+
428
+ impl NumberView {
429
+ fn minimum(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
430
+ bound_to_ruby(ruby, rb_self.minimum.as_ref())
431
+ }
432
+
433
+ fn exclusive_minimum(ruby: &Ruby, rb_self: &Self) -> Value {
434
+ ruby.into_value(rb_self.exclusive_minimum)
435
+ }
436
+
437
+ fn maximum(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
438
+ bound_to_ruby(ruby, rb_self.maximum.as_ref())
439
+ }
440
+
441
+ fn exclusive_maximum(ruby: &Ruby, rb_self: &Self) -> Value {
442
+ ruby.into_value(rb_self.exclusive_maximum)
443
+ }
444
+
445
+ fn multiple_of(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
446
+ divisors_to_ruby(ruby, &rb_self.multiple_of)
447
+ }
448
+
449
+ fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
450
+ Ok(format!(
451
+ "#<JSONSchema::Canonical::NumberView minimum={} exclusive_minimum={} maximum={} exclusive_maximum={} multiple_of={}>",
452
+ Self::minimum(ruby, rb_self)?.inspect(),
453
+ Self::exclusive_minimum(ruby, rb_self).inspect(),
454
+ Self::maximum(ruby, rb_self)?.inspect(),
455
+ Self::exclusive_maximum(ruby, rb_self).inspect(),
456
+ Self::multiple_of(ruby, rb_self)?.inspect()
457
+ ))
458
+ }
459
+
460
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
461
+ let hash = ruby.hash_new();
462
+ hash.aset(ruby.sym_new("minimum"), Self::minimum(ruby, rb_self)?)?;
463
+ hash.aset(
464
+ ruby.sym_new("exclusive_minimum"),
465
+ Self::exclusive_minimum(ruby, rb_self),
466
+ )?;
467
+ hash.aset(ruby.sym_new("maximum"), Self::maximum(ruby, rb_self)?)?;
468
+ hash.aset(
469
+ ruby.sym_new("exclusive_maximum"),
470
+ Self::exclusive_maximum(ruby, rb_self),
471
+ )?;
472
+ hash.aset(
473
+ ruby.sym_new("multiple_of"),
474
+ Self::multiple_of(ruby, rb_self)?,
475
+ )?;
334
476
  Ok(hash)
335
477
  }
336
478
  }
337
479
 
338
- /// An integer value within a closed interval.
480
+ /// An integer value within a closed interval, optionally a multiple of a divisor.
339
481
  #[derive(magnus::TypedData)]
340
482
  #[magnus(class = "JSONSchema::Canonical::IntegerView", free_immediately)]
341
483
  pub struct IntegerView {
342
484
  minimum: Option<serde_json::Number>,
343
485
  maximum: Option<serde_json::Number>,
486
+ multiple_of: Vec<serde_json::Number>,
344
487
  }
345
488
 
346
489
  impl DataTypeFunctions for IntegerView {}
@@ -354,11 +497,16 @@ impl IntegerView {
354
497
  bound_to_ruby(ruby, rb_self.maximum.as_ref())
355
498
  }
356
499
 
500
+ fn multiple_of(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
501
+ divisors_to_ruby(ruby, &rb_self.multiple_of)
502
+ }
503
+
357
504
  fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
358
505
  Ok(format!(
359
- "#<JSONSchema::Canonical::IntegerView minimum={} maximum={}>",
506
+ "#<JSONSchema::Canonical::IntegerView minimum={} maximum={} multiple_of={}>",
360
507
  Self::minimum(ruby, rb_self)?.inspect(),
361
- Self::maximum(ruby, rb_self)?.inspect()
508
+ Self::maximum(ruby, rb_self)?.inspect(),
509
+ Self::multiple_of(ruby, rb_self)?.inspect()
362
510
  ))
363
511
  }
364
512
 
@@ -366,6 +514,275 @@ impl IntegerView {
366
514
  let hash = ruby.hash_new();
367
515
  hash.aset(ruby.sym_new("minimum"), Self::minimum(ruby, rb_self)?)?;
368
516
  hash.aset(ruby.sym_new("maximum"), Self::maximum(ruby, rb_self)?)?;
517
+ hash.aset(
518
+ ruby.sym_new("multiple_of"),
519
+ Self::multiple_of(ruby, rb_self)?,
520
+ )?;
521
+ Ok(hash)
522
+ }
523
+ }
524
+
525
+ /// An array value's constraints.
526
+ #[derive(magnus::TypedData)]
527
+ #[magnus(class = "JSONSchema::Canonical::ArrayView", free_immediately)]
528
+ #[allow(clippy::struct_field_names)]
529
+ pub struct ArrayView {
530
+ min_items: Option<serde_json::Number>,
531
+ max_items: Option<serde_json::Number>,
532
+ unique_items: bool,
533
+ prefix_items: Vec<CanonicalSchema>,
534
+ items: Option<CanonicalSchema>,
535
+ contains: Vec<CoreContainsView>,
536
+ }
537
+
538
+ impl DataTypeFunctions for ArrayView {}
539
+
540
+ impl ArrayView {
541
+ fn min_items(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
542
+ bound_to_ruby(ruby, rb_self.min_items.as_ref())
543
+ }
544
+
545
+ fn max_items(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
546
+ bound_to_ruby(ruby, rb_self.max_items.as_ref())
547
+ }
548
+
549
+ fn unique_items(ruby: &Ruby, rb_self: &Self) -> Value {
550
+ ruby.into_value(rb_self.unique_items)
551
+ }
552
+
553
+ fn prefix_items(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
554
+ let array = ruby.ary_new_capa(rb_self.prefix_items.len());
555
+ for schema in &rb_self.prefix_items {
556
+ array.push(
557
+ ruby.obj_wrap(RbCanonicalSchema {
558
+ inner: schema.clone(),
559
+ })
560
+ .as_value(),
561
+ )?;
562
+ }
563
+ Ok(array.as_value())
564
+ }
565
+
566
+ fn items(ruby: &Ruby, rb_self: &Self) -> Value {
567
+ match &rb_self.items {
568
+ Some(items) => ruby
569
+ .obj_wrap(RbCanonicalSchema {
570
+ inner: items.clone(),
571
+ })
572
+ .as_value(),
573
+ None => ruby.qnil().as_value(),
574
+ }
575
+ }
576
+
577
+ fn contains(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
578
+ let array = ruby.ary_new_capa(rb_self.contains.len());
579
+ for facet in &rb_self.contains {
580
+ array.push(ruby.obj_wrap(ContainsView::from_core(facet)).as_value())?;
581
+ }
582
+ Ok(array.as_value())
583
+ }
584
+
585
+ fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
586
+ Ok(format!(
587
+ "#<JSONSchema::Canonical::ArrayView min_items={} max_items={} unique_items={} prefix_items={} items={} contains={}>",
588
+ Self::min_items(ruby, rb_self)?.inspect(),
589
+ Self::max_items(ruby, rb_self)?.inspect(),
590
+ Self::unique_items(ruby, rb_self).inspect(),
591
+ Self::prefix_items(ruby, rb_self)?.inspect(),
592
+ Self::items(ruby, rb_self).inspect(),
593
+ Self::contains(ruby, rb_self)?.inspect()
594
+ ))
595
+ }
596
+
597
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
598
+ let hash = ruby.hash_new();
599
+ hash.aset(ruby.sym_new("min_items"), Self::min_items(ruby, rb_self)?)?;
600
+ hash.aset(ruby.sym_new("max_items"), Self::max_items(ruby, rb_self)?)?;
601
+ hash.aset(
602
+ ruby.sym_new("unique_items"),
603
+ Self::unique_items(ruby, rb_self),
604
+ )?;
605
+ hash.aset(
606
+ ruby.sym_new("prefix_items"),
607
+ Self::prefix_items(ruby, rb_self)?,
608
+ )?;
609
+ hash.aset(ruby.sym_new("items"), Self::items(ruby, rb_self))?;
610
+ hash.aset(ruby.sym_new("contains"), Self::contains(ruby, rb_self)?)?;
611
+ Ok(hash)
612
+ }
613
+ }
614
+
615
+ /// One `contains` demand of an array. An absent minimum spells the default of one.
616
+ #[derive(magnus::TypedData)]
617
+ #[magnus(class = "JSONSchema::Canonical::ContainsView", free_immediately)]
618
+ pub struct ContainsView {
619
+ schema: CanonicalSchema,
620
+ min_contains: Option<serde_json::Number>,
621
+ max_contains: Option<serde_json::Number>,
622
+ }
623
+
624
+ impl DataTypeFunctions for ContainsView {}
625
+
626
+ impl ContainsView {
627
+ fn from_core(facet: &CoreContainsView) -> Self {
628
+ Self {
629
+ schema: facet.schema.clone(),
630
+ min_contains: facet.min_contains.clone(),
631
+ max_contains: facet.max_contains.clone(),
632
+ }
633
+ }
634
+
635
+ fn schema(ruby: &Ruby, rb_self: &Self) -> Value {
636
+ ruby.obj_wrap(RbCanonicalSchema {
637
+ inner: rb_self.schema.clone(),
638
+ })
639
+ .as_value()
640
+ }
641
+
642
+ fn min_contains(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
643
+ bound_to_ruby(ruby, rb_self.min_contains.as_ref())
644
+ }
645
+
646
+ fn max_contains(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
647
+ bound_to_ruby(ruby, rb_self.max_contains.as_ref())
648
+ }
649
+
650
+ fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
651
+ Ok(format!(
652
+ "#<JSONSchema::Canonical::ContainsView schema={} min_contains={} max_contains={}>",
653
+ Self::schema(ruby, rb_self).inspect(),
654
+ Self::min_contains(ruby, rb_self)?.inspect(),
655
+ Self::max_contains(ruby, rb_self)?.inspect()
656
+ ))
657
+ }
658
+
659
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
660
+ let hash = ruby.hash_new();
661
+ hash.aset(ruby.sym_new("schema"), Self::schema(ruby, rb_self))?;
662
+ hash.aset(
663
+ ruby.sym_new("min_contains"),
664
+ Self::min_contains(ruby, rb_self)?,
665
+ )?;
666
+ hash.aset(
667
+ ruby.sym_new("max_contains"),
668
+ Self::max_contains(ruby, rb_self)?,
669
+ )?;
670
+ Ok(hash)
671
+ }
672
+ }
673
+
674
+ /// An object value's constraints.
675
+ #[derive(magnus::TypedData)]
676
+ #[magnus(class = "JSONSchema::Canonical::ObjectView", free_immediately)]
677
+ pub struct ObjectView {
678
+ min_properties: Option<serde_json::Number>,
679
+ max_properties: Option<serde_json::Number>,
680
+ required: Vec<String>,
681
+ property_names: Option<CanonicalSchema>,
682
+ properties: std::collections::BTreeMap<String, CanonicalSchema>,
683
+ pattern_properties: std::collections::BTreeMap<String, CanonicalSchema>,
684
+ additional_properties: Option<CanonicalSchema>,
685
+ }
686
+
687
+ impl DataTypeFunctions for ObjectView {}
688
+
689
+ impl ObjectView {
690
+ fn min_properties(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
691
+ bound_to_ruby(ruby, rb_self.min_properties.as_ref())
692
+ }
693
+
694
+ fn max_properties(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
695
+ bound_to_ruby(ruby, rb_self.max_properties.as_ref())
696
+ }
697
+
698
+ fn required(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
699
+ let array = ruby.ary_new_capa(rb_self.required.len());
700
+ for key in &rb_self.required {
701
+ array.push(ruby.str_new(key))?;
702
+ }
703
+ Ok(array.as_value())
704
+ }
705
+
706
+ fn property_names(ruby: &Ruby, rb_self: &Self) -> Value {
707
+ match &rb_self.property_names {
708
+ Some(names) => ruby
709
+ .obj_wrap(RbCanonicalSchema {
710
+ inner: names.clone(),
711
+ })
712
+ .as_value(),
713
+ None => ruby.qnil().as_value(),
714
+ }
715
+ }
716
+
717
+ fn properties(ruby: &Ruby, rb_self: &Self) -> Result<RHash, Error> {
718
+ let hash = ruby.hash_new();
719
+ for (key, schema) in &rb_self.properties {
720
+ let wrapped = ruby.obj_wrap(RbCanonicalSchema {
721
+ inner: schema.clone(),
722
+ });
723
+ hash.aset(key.as_str(), wrapped)?;
724
+ }
725
+ Ok(hash)
726
+ }
727
+
728
+ fn pattern_properties(ruby: &Ruby, rb_self: &Self) -> Result<RHash, Error> {
729
+ let hash = ruby.hash_new();
730
+ for (pattern, schema) in &rb_self.pattern_properties {
731
+ let wrapped = ruby.obj_wrap(RbCanonicalSchema {
732
+ inner: schema.clone(),
733
+ });
734
+ hash.aset(pattern.as_str(), wrapped)?;
735
+ }
736
+ Ok(hash)
737
+ }
738
+
739
+ fn additional_properties(ruby: &Ruby, rb_self: &Self) -> Value {
740
+ match &rb_self.additional_properties {
741
+ Some(shield) => ruby
742
+ .obj_wrap(RbCanonicalSchema {
743
+ inner: shield.clone(),
744
+ })
745
+ .as_value(),
746
+ None => ruby.qnil().as_value(),
747
+ }
748
+ }
749
+
750
+ fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
751
+ Ok(format!(
752
+ "#<JSONSchema::Canonical::ObjectView min_properties={} max_properties={} required={} property_names={} properties={} pattern_properties={}>",
753
+ Self::min_properties(ruby, rb_self)?.inspect(),
754
+ Self::max_properties(ruby, rb_self)?.inspect(),
755
+ Self::required(ruby, rb_self)?.inspect(),
756
+ Self::property_names(ruby, rb_self).inspect(),
757
+ Self::properties(ruby, rb_self)?.inspect(),
758
+ Self::pattern_properties(ruby, rb_self)?.inspect()
759
+ ))
760
+ }
761
+
762
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
763
+ let hash = ruby.hash_new();
764
+ hash.aset(
765
+ ruby.sym_new("min_properties"),
766
+ Self::min_properties(ruby, rb_self)?,
767
+ )?;
768
+ hash.aset(
769
+ ruby.sym_new("max_properties"),
770
+ Self::max_properties(ruby, rb_self)?,
771
+ )?;
772
+ hash.aset(ruby.sym_new("required"), Self::required(ruby, rb_self)?)?;
773
+ hash.aset(
774
+ ruby.sym_new("property_names"),
775
+ Self::property_names(ruby, rb_self),
776
+ )?;
777
+ hash.aset(ruby.sym_new("properties"), Self::properties(ruby, rb_self)?)?;
778
+ hash.aset(
779
+ ruby.sym_new("pattern_properties"),
780
+ Self::pattern_properties(ruby, rb_self)?,
781
+ )?;
782
+ hash.aset(
783
+ ruby.sym_new("additional_properties"),
784
+ Self::additional_properties(ruby, rb_self),
785
+ )?;
369
786
  Ok(hash)
370
787
  }
371
788
  }
@@ -560,18 +977,79 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
560
977
  string_view.define_method("min_length", method!(StringView::min_length, 0))?;
561
978
  string_view.define_method("max_length", method!(StringView::max_length, 0))?;
562
979
  string_view.define_method("patterns", method!(StringView::patterns, 0))?;
980
+ string_view.define_method("formats", method!(StringView::formats, 0))?;
981
+ string_view.define_method(
982
+ "content_media_types",
983
+ method!(StringView::content_media_types, 0),
984
+ )?;
985
+ string_view.define_method(
986
+ "content_encodings",
987
+ method!(StringView::content_encodings, 0),
988
+ )?;
563
989
  string_view.define_method("inspect", method!(StringView::inspect, 0))?;
564
990
  string_view.define_method("deconstruct_keys", method!(StringView::deconstruct_keys, 1))?;
565
991
 
992
+ let number_view = canonical_module.define_class("NumberView", ruby.class_object())?;
993
+ number_view.define_method("minimum", method!(NumberView::minimum, 0))?;
994
+ number_view.define_method(
995
+ "exclusive_minimum",
996
+ method!(NumberView::exclusive_minimum, 0),
997
+ )?;
998
+ number_view.define_method("maximum", method!(NumberView::maximum, 0))?;
999
+ number_view.define_method(
1000
+ "exclusive_maximum",
1001
+ method!(NumberView::exclusive_maximum, 0),
1002
+ )?;
1003
+ number_view.define_method("multiple_of", method!(NumberView::multiple_of, 0))?;
1004
+ number_view.define_method("inspect", method!(NumberView::inspect, 0))?;
1005
+ number_view.define_method("deconstruct_keys", method!(NumberView::deconstruct_keys, 1))?;
1006
+
566
1007
  let integer_view = canonical_module.define_class("IntegerView", ruby.class_object())?;
567
1008
  integer_view.define_method("minimum", method!(IntegerView::minimum, 0))?;
568
1009
  integer_view.define_method("maximum", method!(IntegerView::maximum, 0))?;
1010
+ integer_view.define_method("multiple_of", method!(IntegerView::multiple_of, 0))?;
569
1011
  integer_view.define_method("inspect", method!(IntegerView::inspect, 0))?;
570
1012
  integer_view.define_method(
571
1013
  "deconstruct_keys",
572
1014
  method!(IntegerView::deconstruct_keys, 1),
573
1015
  )?;
574
1016
 
1017
+ let array_view = canonical_module.define_class("ArrayView", ruby.class_object())?;
1018
+ array_view.define_method("min_items", method!(ArrayView::min_items, 0))?;
1019
+ array_view.define_method("max_items", method!(ArrayView::max_items, 0))?;
1020
+ array_view.define_method("unique_items", method!(ArrayView::unique_items, 0))?;
1021
+ array_view.define_method("prefix_items", method!(ArrayView::prefix_items, 0))?;
1022
+ array_view.define_method("items", method!(ArrayView::items, 0))?;
1023
+ array_view.define_method("contains", method!(ArrayView::contains, 0))?;
1024
+ array_view.define_method("inspect", method!(ArrayView::inspect, 0))?;
1025
+ array_view.define_method("deconstruct_keys", method!(ArrayView::deconstruct_keys, 1))?;
1026
+ let contains_view = canonical_module.define_class("ContainsView", ruby.class_object())?;
1027
+ contains_view.define_method("schema", method!(ContainsView::schema, 0))?;
1028
+ contains_view.define_method("min_contains", method!(ContainsView::min_contains, 0))?;
1029
+ contains_view.define_method("max_contains", method!(ContainsView::max_contains, 0))?;
1030
+ contains_view.define_method("inspect", method!(ContainsView::inspect, 0))?;
1031
+ contains_view.define_method(
1032
+ "deconstruct_keys",
1033
+ method!(ContainsView::deconstruct_keys, 1),
1034
+ )?;
1035
+
1036
+ let object_view = canonical_module.define_class("ObjectView", ruby.class_object())?;
1037
+ object_view.define_method("min_properties", method!(ObjectView::min_properties, 0))?;
1038
+ object_view.define_method("max_properties", method!(ObjectView::max_properties, 0))?;
1039
+ object_view.define_method("required", method!(ObjectView::required, 0))?;
1040
+ object_view.define_method("property_names", method!(ObjectView::property_names, 0))?;
1041
+ object_view.define_method("properties", method!(ObjectView::properties, 0))?;
1042
+ object_view.define_method(
1043
+ "pattern_properties",
1044
+ method!(ObjectView::pattern_properties, 0),
1045
+ )?;
1046
+ object_view.define_method(
1047
+ "additional_properties",
1048
+ method!(ObjectView::additional_properties, 0),
1049
+ )?;
1050
+ object_view.define_method("inspect", method!(ObjectView::inspect, 0))?;
1051
+ object_view.define_method("deconstruct_keys", method!(ObjectView::deconstruct_keys, 1))?;
1052
+
575
1053
  let any_of_view = canonical_module.define_class("AnyOfView", ruby.class_object())?;
576
1054
  any_of_view.define_method("branches", method!(AnyOfView::branches, 0))?;
577
1055
  any_of_view.define_method("inspect", method!(AnyOfView::inspect, 0))?;