Class: JSI::SchemaSet

Inherits:
Set
  • Object
show all
Defined in:
lib/jsi/schema_set.rb

Overview

a Set of JSI Schemas. always frozen.

any schema instance is described by a set of schemas.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(enum) {|yields| ... } ⇒ SchemaSet

initializes a SchemaSet from the given enum and freezes it.

if a block is given, each element of the enum is passed to it, and the result must be a Schema. if no block is given, the enum must contain only Schemas.

Parameters:

  • enum (#each)

    the schemas to be included in the SchemaSet, or items to be passed to the block

Yield Parameters:

  • yields

    each element of enum for preprocessing into a Schema

Yield Returns:

Raises:



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
# File 'lib/jsi/schema_set.rb', line 42

def initialize(enum, &block)
  if enum.is_a?(Schema)
    raise(ArgumentError, [
      "#{SchemaSet} initialized with a #{Schema}",
      "you probably meant to pass that to #{SchemaSet}[]",
      "or to wrap that schema in a Set or Array for #{SchemaSet}.new",
      "given: #{enum.pretty_inspect.chomp}",
    ].join("\n"))
  end

  unless enum.is_a?(Enumerable)
    raise(ArgumentError, "#{SchemaSet} initialized with non-Enumerable: #{enum.pretty_inspect.chomp}")
  end

  super

  not_schemas = reject { |s| s.is_a?(Schema) }
  if !not_schemas.empty?
    raise(Schema::NotASchemaError, [
      "#{SchemaSet} initialized with non-schema objects:",
      *not_schemas.map { |ns| ns.pretty_inspect.chomp },
    ].join("\n"))
  end

  freeze
end

Class Method Details

.build {|Enumerator::Yielder| ... } ⇒ SchemaSet

Builds a SchemaSet, yielding a yielder to be called with each schema of the SchemaSet.

Yields:

  • (Enumerator::Yielder)

Returns:



13
14
15
# File 'lib/jsi/schema_set.rb', line 13

def build(&block)
  new(Enumerator.new(&block))
end

.ensure_schema_set(schemas) ⇒ SchemaSet

ensures the given param becomes a SchemaSet. returns the param if it is already SchemaSet, otherwise initializes a SchemaSet from it.

Parameters:

  • schemas (SchemaSet, Enumerable)

    the object to ensure becomes a SchemaSet

Returns:

  • (SchemaSet)

    the given SchemaSet, or a SchemaSet initialized from the given Enumerable

Raises:

  • (ArgumentError)

    when the schemas param is not an Enumerable

  • (Schema::NotASchemaError)

    when the schemas param contains objects which are not Schemas



24
25
26
27
28
29
30
# File 'lib/jsi/schema_set.rb', line 24

def ensure_schema_set(schemas)
  if schemas.is_a?(SchemaSet)
    schemas
  else
    new(schemas)
  end
end

Instance Method Details

#child_applicator_schemas(token, instance) ⇒ JSI::SchemaSet

a set of child applicator subschemas of each schema in this set which apply to the child of the given instance on the given token. (see JSI::Schema#child_applicator_schemas)

Parameters:

  • instance (Object)

    the instance to check any child applicators against

Returns:



168
169
170
# File 'lib/jsi/schema_set.rb', line 168

def child_applicator_schemas(token, instance)
  SchemaSet.new(each_child_applicator_schema(token, instance))
end

#each_child_applicator_schema(token, instance) {|JSI::Schema| ... } ⇒ nil, Enumerator

yields each child applicator schema which applies to the child of the given instance on the given token.

Parameters:

  • token (Object)

    the array index or object property name for the child instance

  • instance (Object)

    the instance to check any child applicators against

Yields:

Returns:

  • (nil, Enumerator)

    an Enumerator if invoked without a block; otherwise nil



178
179
180
181
182
183
184
185
186
# File 'lib/jsi/schema_set.rb', line 178

def each_child_applicator_schema(token, instance, &block)
  return to_enum(__method__, token, instance) unless block

  each do |schema|
    schema.each_child_applicator_schema(token, instance, &block)
  end

  nil
end

#each_inplace_applicator_schema(instance) {|JSI::Schema| ... } ⇒ nil, Enumerator

yields each inplace applicator schema which applies to the given instance.

Parameters:

  • instance (Object)

    the instance to check any applicators against

Yields:

Returns:

  • (nil, Enumerator)

    an Enumerator if invoked without a block; otherwise nil



152
153
154
155
156
157
158
159
160
# File 'lib/jsi/schema_set.rb', line 152

def each_inplace_applicator_schema(instance, &block)
  return to_enum(__method__, instance) unless block

  each do |schema|
    schema.each_inplace_applicator_schema(instance, &block)
  end

  nil
end

#inplace_applicator_schemas(instance) ⇒ JSI::SchemaSet

a set of inplace applicator schemas of each schema in this set which apply to the given instance. (see JSI::Schema#inplace_applicator_schemas)

Parameters:

  • instance (Object)

    the instance to check any applicators against

Returns:



143
144
145
# File 'lib/jsi/schema_set.rb', line 143

def inplace_applicator_schemas(instance)
  SchemaSet.new(each_inplace_applicator_schema(instance))
end

#inspectString

Returns:

  • (String)


206
207
208
# File 'lib/jsi/schema_set.rb', line 206

def inspect
  -"#{self.class}[#{map(&:inspect).join(", ")}]"
end

#instance_valid?(instance) ⇒ Boolean

whether the given instance is valid against our schemas

Parameters:

  • instance (Object)

    the instance to validate against our schemas

Returns:

  • (Boolean)


201
202
203
# File 'lib/jsi/schema_set.rb', line 201

def instance_valid?(instance)
  all? { |schema| schema.instance_valid?(instance) }
end

#instance_validate(instance) ⇒ JSI::Validation::Result

validates the given instance against our schemas

Parameters:

  • instance (Object)

    the instance to validate against our schemas

Returns:



192
193
194
195
196
# File 'lib/jsi/schema_set.rb', line 192

def instance_validate(instance)
  inject(Validation::FullResult.new) do |result, schema|
    result.merge(schema.instance_validate(instance))
  end.freeze
end

#new_jsi(instance, uri: nil, register: false, schema_registry: JSI.schema_registry, stringify_symbol_keys: false, to_immutable: DEFAULT_CONTENT_TO_IMMUTABLE, mutable: false) ⇒ JSI::Base subclass

Instantiates a new JSI whose content comes from the given instance param. This SchemaSet indicates the schemas of the JSI - its schemas are inplace applicators of this set's schemas which apply to the given instance.

Parameters:

  • instance (Object)

    the instance to be represented as a JSI

  • uri (#to_str, Addressable::URI) (defaults to: nil)

    The retrieval URI of the instance.

    It is rare that this needs to be specified, and only useful for instances which contain schemas. See JSI::Schema::MetaSchema#new_schema's uri param documentation.

  • register (Boolean) (defaults to: false)

    Whether schema resources in the instantiated JSI will be registered in the schema registry indicated by param schema_registry. This is only useful when the JSI is a schema or contains schemas. The JSI's root will be registered with the uri param, if specified, whether or not the root is a schema.

  • schema_registry (SchemaRegistry, nil) (defaults to: JSI.schema_registry)

    The registry to use for references to other schemas and, depending on register and uri params, to register this JSI and/or any contained schemas with declared URIs.

  • stringify_symbol_keys (Boolean) (defaults to: false)

    Whether the instance content will have any Symbol keys of Hashes replaced with Strings (recursively through the document). Replacement is done on a copy; the given instance is not modified.

  • to_immutable (#call, nil) (defaults to: DEFAULT_CONTENT_TO_IMMUTABLE)

    A proc/callable which takes given instance content and results in an immutable (i.e. deeply frozen) object equal to that. If the instantiated JSI will be mutable, this is not used. Though not recommended, this may be nil with immutable JSIs if the instance content is otherwise guaranteed to be immutable, as well as any modified copies of the instance.

  • mutable (Boolean) (defaults to: false)

    Whether the instantiated JSI will be mutable. The instance content will be transformed with to_immutable if the JSI will be immutable.

Returns:

  • (JSI::Base subclass)

    a JSI whose content comes from the given instance and whose schemas are inplace applicators of the schemas in this set.



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
129
130
131
132
133
134
135
136
# File 'lib/jsi/schema_set.rb', line 98

def new_jsi(instance,
    uri: nil,
    register: false,
    schema_registry: JSI.schema_registry,
    stringify_symbol_keys: false,
    to_immutable: DEFAULT_CONTENT_TO_IMMUTABLE,
    mutable: false
)
  instance = Util.deep_stringify_symbol_keys(instance) if stringify_symbol_keys

  instance = to_immutable.call(instance) if !mutable && to_immutable

  applied_schemas = inplace_applicator_schemas(instance)

  if uri
    unless uri.respond_to?(:to_str)
      raise(TypeError, "uri must be string or Addressable::URI; got: #{uri.inspect}")
    end
    uri = Util.uri(uri)
    unless uri.absolute? && !uri.fragment
      raise(ArgumentError, "uri must be an absolute URI with no fragment; got: #{uri.inspect}")
    end
  end

  jsi_class = JSI::SchemaClasses.class_for_schemas(applied_schemas,
    includes: SchemaClasses.includes_for(instance),
    mutable: mutable,
  )
  jsi = jsi_class.new(instance,
    jsi_indicated_schemas: self,
    jsi_schema_base_uri: uri,
    jsi_schema_registry: schema_registry,
    jsi_content_to_immutable: to_immutable,
  )

  schema_registry.register(jsi) if register && schema_registry

  jsi
end

#pretty_print(q) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/jsi/schema_set.rb', line 214

def pretty_print(q)
  q.text self.class.to_s
  q.text '['
  q.group(2) {
      q.breakable('')
      q.seplist(self, nil, :each) { |e|
        q.pp e
      }
  }
  q.breakable ''
  q.text ']'
end

#to_sObject



210
211
212
# File 'lib/jsi/schema_set.rb', line 210

def to_s
  inspect
end