class Jet::Contract::Attribute

Attributes

checks[R]
type[R]

Public Class Methods

build(*args, &blk) click to toggle source
# File lib/jet/contract/attribute.rb, line 11
def self.build(*args, &blk)
  raise ArgumentError, "no block given" unless block_given?
  Builder.new.instance_eval(&blk).call(*args)
end
new(type, checks = nil, contract: nil, each: nil, required: true, **) click to toggle source
# File lib/jet/contract/attribute.rb, line 16
def initialize(type, checks = nil, contract: nil, each: nil, required: true, **)
  @type = Jet.type_check!("`type`", type, Type)
  @checks = Jet.type_check!("`checks`", checks, Check::Set, NilClass)

  raise ArgumentError, "cannot set both :contract and :each" if contract && each

  @opts = {
    contract: Jet.type_check!(":contract", contract, Contract, NilClass),
    each: Jet.type_check!(":each", each, Attribute, NilClass),
    required: required ? true : false
  }
end

Public Instance Methods

call(input, at = []) click to toggle source
# File lib/jet/contract/attribute.rb, line 29
def call(input, at = [])
  coerce(input).yield_self { |r| result_at(Jet.failure?(r) ? r : check(r.output), at) }
end
check(output) click to toggle source
# File lib/jet/contract/attribute.rb, line 33
def check(output)
  return Result.success if output.nil?
  checks&.(output)&.tap { |r| return r if r.failure? }
  check_contract(output) || check_each(output) || Result.success(output)
end
coerce(input) click to toggle source
# File lib/jet/contract/attribute.rb, line 39
def coerce(input)
  type.(input)
end
is?() click to toggle source
# File lib/jet/contract/attribute.rb, line 43
def is?
  !maybe?
end
maybe?() click to toggle source
# File lib/jet/contract/attribute.rb, line 47
def maybe?
  type.maybe?
end
optional?() click to toggle source
# File lib/jet/contract/attribute.rb, line 51
def optional?
  !required?
end
opts() click to toggle source
# File lib/jet/contract/attribute.rb, line 55
def opts
  @opts.dup
end
required?() click to toggle source
# File lib/jet/contract/attribute.rb, line 59
def required?
  @opts[:required]
end
to_builder() click to toggle source
# File lib/jet/contract/attribute.rb, line 63
def to_builder
  Builder.new(
    checks: @checks&.to_builder,
    contract: @opts[:contract]&.to_builder,
    each: @opts[:each]&.to_builder,
    is: is?,
    required: required?,
    type: type.name
  )
end
to_sym() click to toggle source
# File lib/jet/contract/attribute.rb, line 74
def to_sym
  name
end

Private Instance Methods

check_contract(output) click to toggle source
# File lib/jet/contract/attribute.rb, line 80
def check_contract(output)
  @opts[:contract]&.(output)
end
check_each(output) click to toggle source
# File lib/jet/contract/attribute.rb, line 84
def check_each(output)
  return unless @opts[:each]
  results = output.map.with_index { |v, i| @opts[:each].(v).with(at: [i]) }
  return Result.success(results.map(&:output)) if results.all?(&:success?)
  Result.failure(
    :check_each_failure,
    errors: results.select(&:failure?),
    input: output
  )
end
result_at(result, at) click to toggle source
# File lib/jet/contract/attribute.rb, line 95
def result_at(result, at)
  new_at = Array(at) + Array(result.at)
  result.with(
    at: new_at,
    errors: result.errors.map { |r| result_at(r, new_at) }
  )
end