lib/json_schema/schema.rb in json_schema-0.13.6 vs lib/json_schema/schema.rb in json_schema-0.14.0
- old
+ new
@@ -1,18 +1,31 @@
require "json"
module JsonSchema
class Schema
- @@copyable = []
+ @@copyable_attrs = []
+ # Attributes that are part of the JSON schema and hyper-schema
+ # specifications. These are allowed to be accessed with the [] operator.
+ #
+ # Hash contains the access key mapped to the name of the method that should
+ # be invoked to retrieve a value. For example, `type` maps to `type` and
+ # `additionalItems` maps to `additional_items`.
+ @@schema_attrs = {}
+
# identical to attr_accessible, but allows us to copy in values from a
# target schema to help preserve our hierarchy during reference expansion
def self.attr_copyable(attr)
attr_accessor(attr)
- @@copyable << "@#{attr}".to_sym
+ @@copyable_attrs << "@#{attr}".to_sym
end
+ def self.attr_schema(attr, options = {})
+ attr_copyable(attr)
+ @@schema_attrs[options[:schema_name] || attr] = attr
+ end
+
def self.attr_reader_default(attr, default)
# remove the reader already created by attr_accessor
remove_method(attr)
class_eval("def #{attr} ; !@#{attr}.nil? ? @#{attr} : #{default} ; end")
@@ -69,108 +82,108 @@
# Alters resolution scope. This value is used along with the parent scope's
# URI to build a new address for this schema. Relative ID's will append to
# the parent, and absolute URI's will replace it.
#
# Type: String
- attr_copyable :id
+ attr_schema :id
# Short title of the schema.
#
# Type: String
- attr_copyable :title
+ attr_schema :title
# More detailed description of the schema.
#
# Type: String
- attr_copyable :description
+ attr_schema :description
# Default JSON value for this particular schema
#
# Type: [any]
- attr_copyable :default
+ attr_schema :default
#
# Validation: Any
#
# A collection of subschemas of which data must validate against the full
# set of to be valid.
#
# Type: Array[Schema]
- attr_copyable :all_of
+ attr_schema :all_of, :schema_name => :allOf
# A collection of subschemas of which data must validate against any schema
# in the set to be be valid.
#
# Type: Array[Schema]
- attr_copyable :any_of
+ attr_schema :any_of, :schema_name => :anyOf
# A collection of inlined subschemas. Standard convention is to subschemas
# here and reference them from elsewhere.
#
# Type: Hash[String => Schema]
- attr_copyable :definitions
+ attr_schema :definitions
# A collection of objects that must include the data for it to be valid.
#
# Type: Array
- attr_copyable :enum
+ attr_schema :enum
# A collection of subschemas of which data must validate against exactly
# one of to be valid.
#
# Type: Array[Schema]
- attr_copyable :one_of
+ attr_schema :one_of, :schema_name => :oneOf
# A subschema which data must not validate against to be valid.
#
# Type: Schema
- attr_copyable :not
+ attr_schema :not
# An array of types that data is allowed to be. The spec allows this to be
# a string as well, but the parser will always normalize this to an array
# of strings.
#
# Type: Array[String]
- attr_copyable :type
+ attr_schema :type
# validation: array
- attr_copyable :additional_items
- attr_copyable :items
- attr_copyable :max_items
- attr_copyable :min_items
- attr_copyable :unique_items
+ attr_schema :additional_items, :schema_name => :additionalItems
+ attr_schema :items
+ attr_schema :max_items, :schema_name => :maxItems
+ attr_schema :min_items, :schema_name => :minItems
+ attr_schema :unique_items, :schema_name => :uniqueItems
# validation: number/integer
- attr_copyable :max
- attr_copyable :max_exclusive
- attr_copyable :min
- attr_copyable :min_exclusive
- attr_copyable :multiple_of
+ attr_schema :max
+ attr_schema :max_exclusive, :schema_name => :maxExclusive
+ attr_schema :min
+ attr_schema :min_exclusive, :schema_name => :minExclusive
+ attr_schema :multiple_of, :schema_name => :multipleOf
# validation: object
- attr_copyable :additional_properties
- attr_copyable :dependencies
- attr_copyable :max_properties
- attr_copyable :min_properties
- attr_copyable :pattern_properties
- attr_copyable :properties
- attr_copyable :required
+ attr_schema :additional_properties, :schema_name => :additionalProperties
+ attr_schema :dependencies
+ attr_schema :max_properties, :schema_name => :maxProperties
+ attr_schema :min_properties, :schema_name => :minProperties
+ attr_schema :pattern_properties, :schema_name => :patternProperties
+ attr_schema :properties
+ attr_schema :required
# warning: strictProperties is technically V5 spec (but I needed it now)
- attr_copyable :strict_properties
+ attr_schema :strict_properties, :schema_name => :strictProperties
# validation: string
- attr_copyable :format
- attr_copyable :max_length
- attr_copyable :min_length
- attr_copyable :pattern
+ attr_schema :format
+ attr_schema :max_length, :schema_name => :maxLength
+ attr_schema :min_length, :schema_name => :minLength
+ attr_schema :pattern
# hyperschema
- attr_copyable :links
- attr_copyable :media
- attr_copyable :path_start
- attr_copyable :read_only
+ attr_schema :links
+ attr_schema :media
+ attr_schema :path_start, :schema_name => :pathStart
+ attr_schema :read_only, :schema_name => :readOnly
# Give these properties reader defaults for particular behavior so that we
# can preserve the `nil` nature of their instance variables. Knowing that
# these were `nil` when we read them allows us to properly reflect the
# parsed schema back to JSON.
@@ -195,12 +208,29 @@
alias :max_exclusive? :max_exclusive
alias :min_exclusive? :min_exclusive
alias :read_only? :read_only
alias :unique_items? :unique_items
+ # Allows the values of schema attributes to be accessed with a symbol or a
+ # string. So for example, the value of `schema.additional_items` could be
+ # procured with `schema[:additionalItems]`. This only works for attributes
+ # that are part of the JSON schema specification; other methods on the
+ # class are not available (e.g. `expanded`.)
+ #
+ # This is implemented so that `JsonPointer::Evaluator` can evaluate a
+ # reference on an sintance of this class (as well as plain JSON data).
+ def [](name)
+ name = name.to_sym
+ if @@schema_attrs.key?(name)
+ send(@@schema_attrs[name])
+ else
+ raise NoMethodError, "Schema does not respond to ##{name}"
+ end
+ end
+
def copy_from(schema)
- @@copyable.each do |copyable|
+ @@copyable_attrs.each do |copyable|
instance_variable_set(copyable, schema.instance_variable_get(copyable))
end
end
def expand_references(options = {})
@@ -227,10 +257,10 @@
str += expanded? ? " [EXPANDED]" : " [COLLAPSED]"
str += original? ? " [ORIGINAL]" : " [CLONE]"
str
else
hash = {}
- @@copyable.each do |copyable|
+ @@copyable_attrs.each do |copyable|
next if [:@clones, :@data, :@parent, :@uri].include?(copyable)
if value = instance_variable_get(copyable)
if value.is_a?(Array)
if !value.empty?
hash[copyable] = value.map { |v| inspect_value(v) }