Sha256: 0dbda6b89388e04e3ae0054dcf1e5d220b7066dd91f9f16f3295ab5af639494e

Contents?: true

Size: 1.56 KB

Versions: 1

Compression:

Stored size: 1.56 KB

Contents

# frozen_string_literal: true

require 'bcdd/result'
require 'bcdd/contract'

require_relative 'process/version'
require_relative 'process/caller'
require_relative 'process/input_spec'
require_relative 'process/output_spec'

module BCDD
  module Contracts
    CannotBeNil = BCDD::Contract[-> { _1.nil? and 'cannot be nil' }]
  end

  class Process
    class << self
      attr_reader :__input__, :__input_contract__, :__output__

      def input(&block)
        return @__input__ if defined?(@__input__)

        spec = InputSpec.new
        spec.instance_eval(&block)
        spec.__result__.transform_values!(&:freeze).freeze

        @__input_contract__ = spec.__result__.any? { |_key, value| value.key?(:contract) }
        @__input__ = spec.__result__
      end

      def output(expectations: true, &block)
        @__output__ and raise ArgumentError, 'outputs already defined'

        config = { addon: { given: true, continue: true } }

        if expectations
          spec = OutputSpec.new
          spec.instance_eval(&block)

          output = spec.__result__
          success = output[:success]
          failure = output.fetch(:failure, {}).merge(invalid_input: ::Hash)

          include(Result::Context::Expectations.mixin(config: config, success: success, failure: failure))
        else
          include(Result::Context.mixin(config: config))
        end

        @__output__ = { expectations: expectations }.freeze
      end

      def inherited(subclass)
        subclass.prepend(Caller)
      end

      def call(**input)
        new.call(**input)
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
bcdd-process-0.2.0 lib/bcdd/process.rb