Module: Skooma::Instance::Coercible
- Included in:
- Attribute
- Defined in:
- lib/skooma/instance.rb
Class Method Summary collapse
- .coerce_array_items(value, items_schema) ⇒ Object
- .coerce_value(value, json) ⇒ Object
- .deep_coerce_value(value, json) ⇒ Object
-
.prefix_schema(prefix_items, index) ⇒ Object
The positional subschema for ‘index` when `prefixItems` is present.
-
.schema_object?(node) ⇒ Boolean
True when ‘node` is a real subschema (a JSON object), excluding boolean schemas like `items: true`.
Instance Method Summary collapse
- #coerce(json) ⇒ Object
-
#deep_coerce(json) ⇒ Object
Recursive coercion for parameters only.
Class Method Details
.coerce_array_items(value, items_schema) ⇒ Object
41 42 43 44 45 46 |
# File 'lib/skooma/instance.rb', line 41 def self.coerce_array_items(value, items_schema) return value unless value.is_a?(Array) return value unless schema_object?(items_schema) value.map { |item| item.is_a?(String) ? coerce_value(item, items_schema) : item } end |
.coerce_value(value, json) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/skooma/instance.rb', line 13 def self.coerce_value(value, json) case json["type"] when "integer" begin Integer(value, 10) rescue ArgumentError value end when "number" begin Float(value) rescue ArgumentError value end when "boolean" return true if value == "true" (value == "false") ? false : value when "object" value # convert_object(value, schema) when "array" coerce_array_items(value, json["items"]) else value end end |
.deep_coerce_value(value, json) ⇒ Object
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 |
# File 'lib/skooma/instance.rb', line 61 def self.deep_coerce_value(value, json) return value if value.nil? case json["type"] when "array" return value unless value.is_a?(Array) prefix_items = json["prefixItems"] items = json["items"] value.map.with_index do |item, index| schema = prefix_schema(prefix_items, index) || items schema_object?(schema) ? deep_coerce_value(item, schema) : item end when "object" return value unless value.is_a?(Hash) properties = json["properties"] additional_properties = json["additionalProperties"] value.each_with_object({}) do |(key, item), coerced| schema = properties.respond_to?(:key?) ? properties[key] : nil schema ||= additional_properties coerced[key] = schema_object?(schema) ? deep_coerce_value(item, schema) : item end else # Scalar schema: only scalar values are coercible. A structural value # here means a type mismatch (e.g. `deepObject` against a scalar # schema) — leave it for validation to reject rather than coerce. (value.is_a?(Hash) || value.is_a?(Array)) ? value : coerce_value(value, json) end end |
.prefix_schema(prefix_items, index) ⇒ Object
The positional subschema for ‘index` when `prefixItems` is present.
101 102 103 104 105 |
# File 'lib/skooma/instance.rb', line 101 def self.prefix_schema(prefix_items, index) return unless prefix_items.is_a?(JSONSkooma::JSONNode) && prefix_items.type == "array" prefix_items[index] end |
.schema_object?(node) ⇒ Boolean
True when ‘node` is a real subschema (a JSON object), excluding boolean schemas like `items: true`.
96 97 98 |
# File 'lib/skooma/instance.rb', line 96 def self.schema_object?(node) node.is_a?(JSONSkooma::JSONSchema) && node.type == "object" end |
Instance Method Details
#coerce(json) ⇒ Object
6 7 8 9 10 11 |
# File 'lib/skooma/instance.rb', line 6 def coerce(json) value = self&.value return self if value.nil? Coercible.coerce_value(value, json) end |
#deep_coerce(json) ⇒ Object
Recursive coercion for parameters only. Parameter values arrive as all-strings, so we descend into array items (positional ‘prefixItems` first, then `items`) and object properties (`properties` first, then `additionalProperties`), coercing each to its declared type. Request/response bodies are only shallowly coerced (top level, via `coerce` above), so a nested JSON body value like `“5”` against `integer` stays invalid.
55 56 57 58 59 |
# File 'lib/skooma/instance.rb', line 55 def deep_coerce(json) return if value.nil? Coercible.deep_coerce_value(value, json) end |