Class: Apiwork::Contract::Element

Inherits:
Element
  • Object
show all
Defined in:
lib/apiwork/contract/element.rb

Overview

Block context for defining a single type expression.

Used inside ‘array do` and `variant do` blocks where exactly one element type must be defined.

Examples:

instance_eval style

array :ids do
  integer
end

yield style

array :ids do |element|
  element.integer
end

Array of references

array :items do |element|
  element.reference :item
end

See Also:

Instance Attribute Summary

Attributes inherited from Element

#custom_type, #discriminator, #enum, #format, #inner, #max, #min, #shape, #type, #value

Instance Method Summary collapse

Methods inherited from Element

#array, #binary, #boolean, #date, #datetime, #decimal, #integer, #literal, #number, #object, #record, #string, #time, #union, #unknown, #uuid, #validate!

Constructor Details

#initialize(contract_class) ⇒ Element

Returns a new instance of Element.



29
30
31
32
# File 'lib/apiwork/contract/element.rb', line 29

def initialize(contract_class)
  super()
  @contract_class = contract_class
end

Instance Method Details

#of(type, discriminator: nil, enum: nil, format: nil, max: nil, min: nil, value: nil) {|shape| ... } ⇒ void

This method returns an undefined value.

Defines the element type.

This is the verbose form. Prefer sugar methods (string, integer, etc.) for static definitions. Use ‘of` for dynamic element generation.

Examples:

Dynamic element type

element_type = :string
array :values do
  of element_type
end

Object with block

array :tags do
  of :object do
    string :name
    string :color
  end
end

Parameters:

  • type (Symbol)
    :array, :binary, :boolean, :date, :datetime, :decimal, :integer, :literal, :number, :object, :string, :time, :union, :unknown, :uuid

    The element type. Custom type references are also allowed.

  • discriminator (Symbol, nil) (defaults to: nil)

    (nil) The discriminator field name. Unions only.

  • enum (Array, Symbol, nil) (defaults to: nil)

    (nil) The allowed values or enum reference. Strings and integers only.

  • format (Symbol, nil) (defaults to: nil)

    (nil) [:date, :datetime, :double, :email, :float, :hostname, :int32, :int64, :ipv4, :ipv6, :password, :text, :url, :uuid] Format hint for exports. Does not change the type, but exports may add validation or documentation based on it. Valid formats by type: ‘:decimal`/`:number` (`:double`, `:float`), `:integer` (`:int32`, `:int64`), `:string` (`:date`, `:datetime`, `:email`, `:hostname`, `:ipv4`, `:ipv6`, `:password`, `:text`, `:url`, `:uuid`).

  • max (Integer, nil) (defaults to: nil)

    (nil) The maximum. For ‘:decimal`, `:integer`, `:number`: value. For `:string`: length.

  • min (Integer, nil) (defaults to: nil)

    (nil) The minimum. For ‘:decimal`, `:integer`, `:number`: value. For `:string`: length.

  • value (Object, nil) (defaults to: nil)

    (nil) The literal value. Literals only.

Yields:

  • block for defining nested structure (instance_eval style)

Yield Parameters:

Raises:

  • (ArgumentError)

    if object, array, or union type is missing block



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
# File 'lib/apiwork/contract/element.rb', line 74

def of(type, discriminator: nil, enum: nil, format: nil, max: nil, min: nil, value: nil, &block)
  resolved_enum = enum.is_a?(Symbol) ? resolve_enum(enum) : enum

  case type
  when :string, :integer, :decimal, :boolean, :number, :datetime, :date, :uuid, :time, :binary, :unknown
    set_type(type, format:, max:, min:, enum: resolved_enum)
  when :literal
    @type = :literal
    @value = value
    @defined = true
  when :object
    @type = :object
    if block
      shape = Object.new(@contract_class)
      block.arity.positive? ? yield(shape) : shape.instance_eval(&block)
      @shape = shape
    end
    @defined = true
  when :array
    raise ConfigurationError, 'array requires a block' unless block

    inner = Element.new(@contract_class)
    block.arity.positive? ? yield(inner) : inner.instance_eval(&block)
    inner.validate!
    @type = :array
    @inner = inner
    @shape = inner.shape
    @defined = true
  when :record
    raise ConfigurationError, 'record requires a block' unless block

    inner = Element.new(@contract_class)
    block.arity.positive? ? yield(inner) : inner.instance_eval(&block)
    inner.validate!
    @type = :record
    @inner = inner
    @defined = true
  when :union
    raise ConfigurationError, 'union requires a block' unless block

    shape = Union.new(@contract_class, discriminator:)
    block.arity.positive? ? yield(shape) : shape.instance_eval(&block)
    @type = :union
    @shape = shape
    @discriminator = discriminator
    @defined = true
  else
    @type = type
    @custom_type = type
    @defined = true
  end
end

#reference(type_name) ⇒ Object



127
128
129
130
131
# File 'lib/apiwork/contract/element.rb', line 127

def reference(type_name)
  @type = type_name
  @custom_type = type_name
  @defined = true
end