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:



30
31
32
33
34
35
36
37
38
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
# File 'lib/jsi/schema_set.rb', line 30

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(&nil) # note super() does implicitly pass block without &nil
  if COMPARE_BY_IDENTITY_DEFINED
    compare_by_identity
  else
    # TODO rm when Set#compare_by_identity is universally available.
    # note does not work on JRuby, but JRuby has Set#compare_by_identity.
    @hash.compare_by_identity
  end

  if block
    enum.each_entry { |o| add(block[o]) }
  else
    merge(enum)
  end

  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:



16
17
18
# File 'lib/jsi/schema_set.rb', line 16

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

Instance Method Details

#each_yield_set {|Schema, #to_proc| ... } ⇒ SchemaSet

Builds a SchemaSet, yielding each schema and a callable to be called with each schema of the resulting SchemaSet.

Yields:

Returns:



169
170
171
172
173
174
# File 'lib/jsi/schema_set.rb', line 169

def each_yield_set(&block)
  self.class.new(Enumerator.new do |y|
    c = y.method(:yield) # TODO drop c, just pass y, when all supported Enumerator::Yielder.method_defined?(:to_proc)
    each { |schema| yield(schema, c) }
  end)
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)


157
158
159
# File 'lib/jsi/schema_set.rb', line 157

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:



148
149
150
151
152
# File 'lib/jsi/schema_set.rb', line 148

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

#jsi_schema_modulesSet<SchemaModule>

Returns:



162
163
164
# File 'lib/jsi/schema_set.rb', line 162

def jsi_schema_modules
  Set.new(self, &:jsi_schema_module).freeze
end

#new_jsi(instance, base_uri: nil, register: false, stringify_symbol_keys: false, mutable: false, **conf_kw) ⇒ Base

Instantiates a new JSI whose content comes from the given instance param.

The schemas of the JSI (its Base#jsi_schemas) are in-place applicators of this set's schemas which apply to the given instance. The JSI's Base#jsi_indicated_schemas set is this set.

The resulting JSI is an instance of a number of modules:

Parameters:

  • instance (Object)

    the instance to be represented as a JSI

  • base_uri (#to_str, URI, nil) (defaults to: nil)

    The base URI of the instance document. An absolute URI.

    It is rare that this needs to be specified. It is useful when the instance contains schemas, and schemas in the document use relative URIs for $id or $ref without an absolute id in an ancestor schema - those URIs will be resolved relative to base_uri.

    See also conf root_uri. base_uri is not used to identify any resource, only to resolve relative URIs. root_uri does identify the root resource.

  • register (Boolean) (defaults to: false)

    Whether schema resources in the instantiated JSI will be registered in the configured registry. This is only useful when the JSI is a schema or contains schemas.

  • 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.

  • mutable (Boolean) (defaults to: false)

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

  • conf_kw

    Additional keyword params are passed to initialize a Base::Conf, the JSI's Base#jsi_conf.

Returns:

  • (Base)

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

Raises:



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
137
138
139
140
141
142
# File 'lib/jsi/schema_set.rb', line 106

def new_jsi(instance,
    base_uri: nil,
    register: false,
    stringify_symbol_keys: false,
    mutable: false,
    **conf_kw
)
  raise(BlockGivenError) if block_given?

  conf = Base::Conf.new(**conf_kw)

  instance = Util.deep_stringify_symbol_keys(instance) if stringify_symbol_keys

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

  applied_schemas = SchemaSet.build do |y|
    c = y.method(:yield) # TODO drop c, just pass y, when all supported Enumerator::Yielder.method_defined?(:to_proc)
    each { |is| is.each_inplace_applicator_schema(instance, &c) }
  end

  base_uri = Util.uri(base_uri, nnil: false, yabs: true) || conf.root_uri

  jsi_class = JSI::SchemaClasses.class_for_schemas(applied_schemas,
    includes: SchemaClasses.includes_for(instance),
    mutable: mutable,
  )
  jsi = jsi_class.new(
    jsi_document: instance,
    jsi_indicated_schemas: self,
    jsi_base_uri: base_uri,
    jsi_conf: conf,
  ).send(:jsi_initialized)

  conf.registry.register(jsi) if register && conf.registry

  jsi
end