Class: Dry::Schema::DSL

Inherits:
Object
  • Object
show all
Extended by:
Initializer
Defined in:
lib/dry/schema/dsl.rb

Overview

The schema definition DSL class

The DSL is exposed by:

- `Schema.define`
- `Schema.Params`
- `Schema.JSON`
- `Schema::Params.define` - use with sub-classes
- `Schema::JSON.define` - use with sub-classes

Examples:

class-based definition

class UserSchema < Dry::Schema::Params
  define do
    required(:name).filled
    required(:age).filled(:integer, gt: 18)
  end
end

user_schema = UserSchema.new
user_schema.(name: 'Jame', age: 21)

instance-based definition shortcut

UserSchema = Dry::Schema.Params do
  required(:name).filled
  required(:age).filled(:integer, gt: 18)
end

UserSchema.(name: 'Jame', age: 21)

Constant Summary collapse

Types =
Schema::Types

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#compilerCompiler (readonly)

Returns The rule compiler object.

Returns:

  • (Compiler)

    The rule compiler object



55
# File 'lib/dry/schema/dsl.rb', line 55

option :compiler, default: -> { Compiler.new }

#configConfig (readonly)

Returns Configuration object exposed via ‘#configure` method.

Returns:

  • (Config)

    Configuration object exposed via ‘#configure` method



75
# File 'lib/dry/schema/dsl.rb', line 75

option :config, optional: true, default: -> { Config.new }

#macrosArray (readonly)

Returns An array with macros defined within the DSL.

Returns:

  • (Array)

    An array with macros defined within the DSL



63
# File 'lib/dry/schema/dsl.rb', line 63

option :macros, default: -> { EMPTY_ARRAY.dup }

#parentDSL (readonly)

Returns An optional parent DSL object that will be used to merge keys and rules.

Returns:

  • (DSL)

    An optional parent DSL object that will be used to merge keys and rules



71
# File 'lib/dry/schema/dsl.rb', line 71

option :parent, optional: true

#processor_typeCompiler (readonly)

Returns The type of the processor (Params, JSON, or a custom sub-class).

Returns:

  • (Compiler)

    The type of the processor (Params, JSON, or a custom sub-class)



59
# File 'lib/dry/schema/dsl.rb', line 59

option :processor_type, default: -> { Processor }

#typesCompiler (readonly)

Returns A key=>type map defined within the DSL.

Returns:

  • (Compiler)

    A key=>type map defined within the DSL



67
# File 'lib/dry/schema/dsl.rb', line 67

option :types, default: -> { EMPTY_HASH.dup }

Class Method Details

.new(**options, &block) ⇒ DSL

Build a new DSL object and evaluate provided block

Parameters:

  • options (Hash)

Options Hash (**options):

  • :processor (Class)

    The processor type (‘Params`, `JSON` or a custom sub-class)

  • :compiler (Compiler)

    An instance of a rule compiler (must be compatible with ‘Schema::Compiler`) (optional)

  • :parent (DSL)

    An instance of the parent DSL (optional)

  • :config (Config)

    A configuration object (optional)

Returns:

See Also:



93
94
95
96
97
# File 'lib/dry/schema/dsl.rb', line 93

def self.new(**options, &block)
  dsl = super
  dsl.instance_eval(&block) if block
  dsl
end

Instance Method Details

#arrayDry::Types::Array::Member

A shortcut for defining an array type with a member

Examples:

required(:tags).filled(array[:string])

Returns:

  • (Dry::Types::Array::Member)


205
206
207
# File 'lib/dry/schema/dsl.rb', line 205

def array
  -> member_type { type_registry["array"].of(resolve_type(member_type)) }
end

#callProcessor

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build a processor based on DSL’s definitions

Returns:



182
183
184
185
186
187
188
# File 'lib/dry/schema/dsl.rb', line 182

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

#configure(&block) ⇒ DSL

Provide customized configuration for your schema

Examples:

Dry::Schema.define do
  configure do |config|
    config.messages = :i18n
  end
end

Returns:

See Also:



113
114
115
116
# File 'lib/dry/schema/dsl.rb', line 113

def configure(&block)
  config.configure(&block)
  self
end

#key(name, macro:, &block) ⇒ Macros::Key

A generic method for defining keys

Parameters:

  • name (Symbol)

    The key name

  • macro (Class)

    The macro sub-class (ie ‘Macros::Required` or any other `Macros::Key` subclass)

Returns:



162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/dry/schema/dsl.rb', line 162

def key(name, macro:, &block)
  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

#maybe?(type) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if the given type is a maybe sum

Returns:

  • (Boolean)


245
246
247
# File 'lib/dry/schema/dsl.rb', line 245

def maybe?(type)
  type.is_a?(Dry::Types::Sum) && type.left.primitive.equal?(NilClass)
end

#new(&block) ⇒ Dry::Types::Safe

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a new DSL instance using the same processor type

Returns:

  • (Dry::Types::Safe)


223
224
225
# File 'lib/dry/schema/dsl.rb', line 223

def new(&block)
  self.class.new(processor_type: processor_type, &block)
end

#optional(name, &block) ⇒ Macros::Optional

Define an optional key

This works exactly the same as ‘required` except that if a key is not present rules will not be applied

Parameters:

  • name (Symbol)

    The key name

Returns:

See Also:



150
151
152
# File 'lib/dry/schema/dsl.rb', line 150

def optional(name, &block)
  key(name, macro: Macros::Optional, &block)
end

#required(name, &block) ⇒ Macros::Required

Define a required key

Examples:

required(:name).filled

required(:age).value(:integer)

required(:user_limit).value(:integer, gt?: 0)

required(:tags).filled { array? | str? }

Parameters:

  • name (Symbol)

    The key name

Returns:



134
135
136
# File 'lib/dry/schema/dsl.rb', line 134

def required(name, &block)
  key(name, macro: Macros::Required, &block)
end

#set_type(name, spec) ⇒ Dry::Types::Safe

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Set a type for the given key name

Parameters:

  • name (Symbol)

    The key name

  • spec (Symbol, Array<Symbol>, Dry::Types::Type)

    The type spec or a type object

Returns:

  • (Dry::Types::Safe)


235
236
237
238
239
240
# File 'lib/dry/schema/dsl.rb', line 235

def set_type(name, spec)
  type = resolve_type(spec)
  meta = { omittable: true, maybe: maybe?(type) }

  types[name] = type.meta(meta)
end

#to_ruleRuleApplier

Cast this DSL into a rule object

Returns:



193
194
195
# File 'lib/dry/schema/dsl.rb', line 193

def to_rule
  call.to_rule
end

#type_schemaDry::Types::Safe

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return type schema used by the value coercer

Returns:

  • (Dry::Types::Safe)


214
215
216
# File 'lib/dry/schema/dsl.rb', line 214

def type_schema
  type_registry["hash"].schema(types.merge(parent_types)).safe
end