Class: AnyVali::ObjectSchema
- Defined in:
- lib/anyvali/schemas/object_schema.rb
Constant Summary
Constants inherited from Schema
Schema::RESERVED_METADATA_KEYS
Instance Attribute Summary collapse
-
#properties ⇒ Object
readonly
Returns the value of attribute properties.
-
#required_keys ⇒ Object
readonly
Returns the value of attribute required_keys.
-
#unknown_keys ⇒ Object
readonly
Returns the value of attribute unknown_keys.
Attributes inherited from Schema
#coerce_config, #constraints, #custom_validators, #default_value, #has_default, #kind, #metadata
Instance Method Summary collapse
- #allow_unknown ⇒ Object
-
#initialize(properties:, required: [], unknown_keys: "strip", unknown_keys_explicit: false, **kwargs) ⇒ ObjectSchema
constructor
A new instance of ObjectSchema.
- #safe_parse(input, path: [], context: nil) ⇒ Object
- #strict ⇒ Object
- #strip_unknown ⇒ Object
- #to_node ⇒ Object
Methods inherited from Schema
#coerce, #default, #describe, #export, #parse, #portable?, #refine, type_name, #with_metadata
Constructor Details
#initialize(properties:, required: [], unknown_keys: "strip", unknown_keys_explicit: false, **kwargs) ⇒ ObjectSchema
Returns a new instance of ObjectSchema.
7 8 9 10 11 12 13 |
# File 'lib/anyvali/schemas/object_schema.rb', line 7 def initialize(properties:, required: [], unknown_keys: "strip", unknown_keys_explicit: false, **kwargs) @properties = properties.freeze @required_keys = required.freeze @unknown_keys = unknown_keys @unknown_keys_explicit = unknown_keys_explicit super(kind: "object", **kwargs) end |
Instance Attribute Details
#properties ⇒ Object (readonly)
Returns the value of attribute properties.
5 6 7 |
# File 'lib/anyvali/schemas/object_schema.rb', line 5 def properties @properties end |
#required_keys ⇒ Object (readonly)
Returns the value of attribute required_keys.
5 6 7 |
# File 'lib/anyvali/schemas/object_schema.rb', line 5 def required_keys @required_keys end |
#unknown_keys ⇒ Object (readonly)
Returns the value of attribute unknown_keys.
5 6 7 |
# File 'lib/anyvali/schemas/object_schema.rb', line 5 def unknown_keys @unknown_keys end |
Instance Method Details
#allow_unknown ⇒ Object
23 24 25 |
# File 'lib/anyvali/schemas/object_schema.rb', line 23 def allow_unknown dup_with(unknown_keys: "allow", unknown_keys_explicit: true) end |
#safe_parse(input, path: [], context: nil) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/anyvali/schemas/object_schema.rb', line 39 def safe_parse(input, path: [], context: nil) context ||= ValidationContext.new issues = [] unless input.is_a?(Hash) issues << ValidationIssue.new( code: IssueCodes::INVALID_TYPE, path: path, expected: "object", received: Schema.type_name(input) ) return ParseResult.new(value: nil, issues: issues) end output = {} # Check required fields @required_keys.each do |key| unless input.key?(key) prop_schema = @properties[key] expected = prop_schema ? prop_schema.kind : "unknown" issues << ValidationIssue.new( code: IssueCodes::REQUIRED, path: path + [key], expected: expected, received: "undefined" ) end end # Validate known properties @properties.each do |key, prop_schema| if input.key?(key) # Value is present val = input[key] # Handle default on property schema (value is present, don't apply default) result = prop_schema.safe_parse(val, path: path + [key], context: context) if result.success? output[key] = result.value else issues.concat(result.issues) end elsif prop_schema.has_default # Apply default default_val = prop_schema.default_value # Validate the default value result = prop_schema.safe_parse(default_val, path: path + [key], context: context) if result.success? output[key] = result.value else # Default is invalid issues << ValidationIssue.new( code: IssueCodes::DEFAULT_INVALID, path: path + [key], expected: result.issues.first&.expected || prop_schema.kind, received: default_val.to_s ) end elsif prop_schema.is_a?(OptionalSchema) # Optional field absent - OK elsif !@required_keys.include?(key) # Non-required field absent without default - OK end end # Handle unknown keys unknown = input.keys - @properties.keys case effective_unknown_keys when "reject" unknown.each do |key| issues << ValidationIssue.new( code: IssueCodes::UNKNOWN_KEY, path: path + [key], expected: "undefined", received: key ) end when "strip" # Just don't include them when "allow" unknown.each { |key| output[key] = input[key] } end if issues.empty? ParseResult.new(value: output, issues: []) else ParseResult.new(value: nil, issues: issues) end end |
#strict ⇒ Object
15 16 17 |
# File 'lib/anyvali/schemas/object_schema.rb', line 15 def strict dup_with(unknown_keys: "reject", unknown_keys_explicit: true) end |
#strip_unknown ⇒ Object
19 20 21 |
# File 'lib/anyvali/schemas/object_schema.rb', line 19 def strip_unknown dup_with(unknown_keys: "strip", unknown_keys_explicit: true) end |
#to_node ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/anyvali/schemas/object_schema.rb', line 27 def to_node node = super props = {} @properties.each do |k, v| props[k] = v.to_node end node["properties"] = props node["required"] = @required_keys node["unknownKeys"] = export_unknown_keys node end |