class Jet::Contract::Attribute::Builder
Public Class Methods
new(opts = {})
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 7 def initialize(opts = {}) @opts = { required: true }.merge(opts) checks(opts[:checks]) if opts[:checks] contract(opts[:contract]) if opts[:contract] each(*opts[:each]) if opts[:each] end
Public Instance Methods
call(types = nil, checks = nil)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 14 def call(types = nil, checks = nil) types = types.nil? ? Contract.types : Contract.types!(types) checks = checks.nil? ? Contract.checks : Contract.checks!(checks) Attribute.new( type_with(types), check_set_with(checks), contract: @opts[:contract]&.(types, checks), each: @opts[:each]&.(types, checks), required: @opts[:required] ) end
checks(checks)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 27 def checks(checks) @opts[:checks] = checks.each_with_object([]) do |check, a| case check when Hash check.each { |(k, v)| a << [k.to_sym, v] } when Array a << [check.first.to_sym].concat(check[1..-1]) else a << [check.to_sym] end end self end
contract(contract = nil, &blk)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 41 def contract(contract = nil, &blk) raise ArgumentError, "cannot provide :contract if :each is set" if @opts[:each] auto_type!("contract", :hash) raise ArgumentError, "must provide either `contract` or a block" unless !contract.nil? ^ block_given? @opts[:contract] = if block_given? Contract::Builder.new.tap { |b| b.instance_eval(&blk) } else Jet.type_check!(":contract", contract, Contract, Contract::Builder) end self end
each(*args, &blk)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 56 def each(*args, &blk) raise ArgumentError, "cannot provide :each if :contract is set" if @opts[:contract] auto_type!("each", :array) raise ArgumentError, "must provide either `args` or a block" unless args.any? ^ block_given? @opts[:each] = if block_given? self.class.new.instance_eval(&blk) elsif args.size == 1 && args.first.is_a?(self.class) args.first else self.class.new.is(*args) end self end
is(type, *checks)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 73 def is(type, *checks) @opts[:maybe] = false type(type, *checks) self end
maybe(type, *checks)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 79 def maybe(type, *checks) @opts[:maybe] = true type(type, *checks) self end
opts()
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 91 def opts @opts.dup end
type(type, *checks)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 85 def type(type, *checks) @opts[:type] = Jet.type_check!("`type`", type, Symbol, Type).to_sym checks(checks) self end
Private Instance Methods
auto_type!(method, type)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 97 def auto_type!(method, type) type(type) unless @opts[:type] raise ArgumentError, "##{method} can only be used with type :#{type}" unless @opts[:type] == type type end
check_set_with(checks)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 104 def check_set_with(checks) return unless @opts[:checks]&.any? Check::Set.new(*@opts[:checks].map { |name, *args| [checks[name]].concat(args) }) end
type_with(types)
click to toggle source
# File lib/jet/contract/attribute/builder.rb, line 109 def type_with(types) type = types.fetch(@opts[:type].to_sym) return type.maybe if @opts[:maybe] raise "#{type.inspect} is a maybe? type (hint: use #maybe instead of #is)" if type.maybe? type end