Module: BCDD::Contract::Unit::Factory

Defined in:
lib/bcdd/contract/unit/factory.rb

Constant Summary collapse

ArityOneHandler =
->(strategy) do
  ->(value, err) do
    outcome = strategy.call(value)

    err << outcome if outcome.is_a?(::String)
  end
end

Class Method Summary collapse

Class Method Details

.build(arg) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/bcdd/contract/unit/factory.rb', line 9

def self.build(arg)
  return arg if arg.is_a?(Core::Checker)

  return Registry.unit(arg) if arg.is_a?(::Symbol)

  return type!(::NilClass) if arg.nil?

  arg.is_a?(::Proc) ? lambda!(arg) : type!(arg)
end

.lambda!(arg) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/bcdd/contract/unit/factory.rb', line 28

def self.lambda!(arg)
  (arg.is_a?(::Proc) && arg.lambda?) or raise ::ArgumentError, 'must be a lambda'

  strategy =
    case arg.arity
    when 1 then ArityOneHandler[arg]
    when 2 then arg
    else raise ::ArgumentError, 'must have two arguments (value, errors)'
    end

  new(strategy)
end

.new(strategy) ⇒ Object



5
6
7
# File 'lib/bcdd/contract/unit/factory.rb', line 5

def self.new(strategy)
  Core::Factory.new(Unit::Checker, Unit::Checking, strategy)
end

.type!(arg) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/bcdd/contract/unit/factory.rb', line 41

def self.type!(arg)
  arg.is_a?(::Module) or raise ::ArgumentError, format('%p must be a class, module or lambda', arg)

  cache_item = Registry.unit(arg)

  return cache_item if cache_item

  checker = lambda!(->(value, err) { err << "%p must be a #{arg.name}" unless value.is_a?(arg) })

  Registry.write(arg, checker)
end