class Dry::Schema::DSL

@api public
UserSchema.(name: ‘Jame’, age: 21)
end
required(:age).filled(:integer, gt: 18)
required(:name).filled
UserSchema = Dry::Schema.Params do
@example instance-based definition shortcut
user_schema.(name: ‘Jame’, age: 21)
user_schema = UserSchema.new
end
end
required(:age).filled(:integer, gt: 18)
required(:name).filled
define do
class UserSchema < Dry::Schema::Params
@example class-based definition
- ‘Schema::JSON.define` - use with sub-classes
- `Schema::Params.define` - use with sub-classes
- `Schema.JSON`
- `Schema.Params`
- `Schema.define`
The DSL is exposed by:
The schema definition DSL class

def self.new(**options, &block)

Other tags:
    Api: - public

Returns:
  • (DSL) -

Other tags:
    See: Processor.define -
    See: Schema.JSON -
    See: Schema.Params -
    See: Schema.define -

Options Hash: (**options)
  • :config (Config) -- A configuration object (optional)
  • :parent (DSL) -- An instance of the parent DSL (optional)
  • :compiler (Compiler) -- An instance of a rule compiler (must be compatible with `Schema::Compiler`) (optional)
  • :processor (Class) -- The processor type (`Params`, `JSON` or a custom sub-class)

Parameters:
  • options (Hash) --
def self.new(**options, &block)
  dsl = super
  dsl.instance_eval(&block) if block
  dsl
end

def array

Other tags:
    Api: - public

Returns:
  • (Dry::Types::Array::Member) -
def array
  -> member_type { type_registry['array'].of(resolve_type(member_type)) }
end

def call

Other tags:
    Api: - private

Returns:
  • (Processor) -
def call
  steps = [key_coercer]
  steps << filter_schema.rule_applier if filter_rules?
  steps << value_coercer << rule_applier
  processor_type.new { |processor| steps.each { |step| processor << step } }
end

def configure(&block)

Other tags:
    Api: - public

Returns:
  • (DSL) -

Other tags:
    See: Config -
def configure(&block)
  config.configure(&block)
  self
end

def filter_rules?

Other tags:
    Api: - private
def filter_rules?
  instance_variable_defined?('@__filter_schema__') && !filter_schema.macros.empty?
end

def filter_schema

Other tags:
    Api: - private

Other tags:
    See: Macros::Value#filter -
def filter_schema
  @__filter_schema__ ||= new
end

def key(name, macro:, &block)

Other tags:
    Api: - public

Returns:
  • (Macros::Key) -

Parameters:
  • macro (Class) -- The macro sub-class (ie `Macros::Required` or any other `Macros::Key` subclass)
  • name (Symbol) -- The key name
def key(name, macro:, &block)
  raise ArgumentError, "Key +#{name}+ is not a symbol" unless name.is_a?(::Symbol)
  set_type(name, Types::Any)
  macro = macro.new(
    name: name,
    compiler: compiler,
    schema_dsl: self,
    filter_schema: filter_schema
  )
  macro.value(&block) if block
  macros << macro
  macro
end

def key_coercer

Other tags:
    Api: - private

Returns:
  • (KeyCoercer) -
def key_coercer
  KeyCoercer.symbolized(key_map + parent_key_map)
end

def key_map(types = self.types)

Other tags:
    Api: - protected
def key_map(types = self.types)
  keys = types.map { |key, type| key_spec(key, type) }
  km = KeyMap.new(keys)
  if key_map_type
    km.public_send(key_map_type)
  else
    km
  end
end

def key_map_type

Other tags:
    Api: - private
def key_map_type
  processor_type.config.key_map_type
end

def key_spec(name, type)

Other tags:
    Api: - private
def key_spec(name, type)
  if type.respond_to?(:keys)
    { name => key_map(type.name_key_map) }
  elsif type.respond_to?(:member)
    kv = key_spec(name, type.member)
    kv.equal?(name) ? name : kv.flatten(1)
  else
    name
  end
end

def new(&block)

Other tags:
    Api: - private

Returns:
  • (Dry::Types::Safe) -
def new(&block)
  self.class.new(processor_type: processor_type, &block)
end

def optional(name, &block)

Other tags:
    Api: - public

Returns:
  • (Macros::Optional) -

Parameters:
  • name (Symbol) -- The key name

Other tags:
    See: DSL#required -
def optional(name, &block)
  key(name, macro: Macros::Optional, &block)
end

def parent_key_map

Other tags:
    Api: - private
def parent_key_map
  parent&.key_map || EMPTY_ARRAY
end

def parent_rules

Other tags:
    Api: - private
def parent_rules
  parent&.rules || EMPTY_HASH
end

def required(name, &block)

Other tags:
    Api: - public

Returns:
  • (Macros::Required) -

Parameters:
  • name (Symbol) -- The key name
def required(name, &block)
  key(name, macro: Macros::Required, &block)
end

def resolve_type(spec)

Other tags:
    Api: - private

Returns:
  • (Dry::Types::Type) -

Parameters:
  • (Symbol, Array, Dry::Types::Type) --
def resolve_type(spec)
  case spec
  when ::Dry::Types::Type then spec
  when ::Array then spec.map { |s| resolve_type(s) }.reduce(:|)
  else
    type_registry[spec]
  end
end

def rule_applier

Other tags:
    Api: - protected

Returns:
  • (RuleApplier) -
def rule_applier
  RuleApplier.new(rules, config: config)
end

def rules

Other tags:
    Api: - protected

Other tags:
    See: #rule_applier -
def rules
  parent_rules.merge(macros.map { |m| [m.name, m.to_rule] }.to_h.compact)
end

def set_type(name, spec)

Other tags:
    Api: - private

Returns:
  • (Dry::Types::Safe) -

Parameters:
  • spec (Symbol, Array, Dry::Types::Type) -- The type spec or a type object
  • name (Symbol) -- The key name
def set_type(name, spec)
  type = resolve_type(spec)
  meta = { required: false, maybe: type.optional? }
  types[name] = type.meta(meta)
end

def to_rule

Returns:
  • (RuleApplier) -
def to_rule
  call.to_rule
end

def type_registry

Other tags:
    Api: - private
def type_registry
  processor_type.config.type_registry
end

def type_schema

Other tags:
    Api: - private

Returns:
  • (Dry::Types::Safe) -
def type_schema
  if parent
    parent.type_schema.schema(types)
  else
    type_registry['hash'].schema(types).lax
  end
end

def value_coercer

Other tags:
    Api: - private

Returns:
  • (ValueCoercer) -
def value_coercer
  ValueCoercer.new(type_schema)
end