Sha256: 5973fd85748f7e23946a2daa9e35b056935185d8a7fc9dc1736ede69a32f242b

Contents?: true

Size: 1.27 KB

Versions: 1

Compression:

Stored size: 1.27 KB

Contents

# frozen_string_literal: true

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

    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

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

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

    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

    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
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
bcdd-contract-0.1.0 lib/bcdd/contract/unit/factory.rb