Sha256: 7ae8b2acb5b9387edd341f3fcb1535d8b0ba6652003e783bd9f09556722f0534

Contents?: true

Size: 1.42 KB

Versions: 1

Compression:

Stored size: 1.42 KB

Contents

# frozen_string_literal: true

require 'dry-types'

require 'atacama/contract/parameter'
require 'atacama/contract/validator'
require 'atacama/contract/context'

module Atacama
  # The type namespace to interact with DRY::Types
  module Types
    include Dry::Types.module
    Boolean = Types::True | Types::False
    ContextOrHash = Strict::Hash | Instance(Context)
  end

  # This class enables a DSL for creating a contract for the initializer
  class Contract
    RESERVED_KEYS = %i[call initialize context].freeze

    NameInterface = Types::Strict::Symbol.constrained(excluded_from: RESERVED_KEYS)

    class << self
      def options
        @options ||= {}
      end

      # Define an initializer value.
      # @param [Symbol] name of the argument
      def option(name, **kwargs)
        # Validate it's a symbol and not reserved
        name = NameInterface[name]

        options[name] = Parameter.new(name: name, **kwargs)

        define_method(name) { @context[name] }
        define_method("#{name}?") { !!@context[name] }
      end

      def call(context = {})
        new(context: context).call
      end
    end

    attr_reader :context

    def initialize(context: {}, **)
      # Validate the type
      Types::ContextOrHash[context]
      @context = context.is_a?(Context) ? context : Context.new(context)
      Validator.call(options: self.class.options, context: @context)
    end

    def call
      self
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
atacama-0.1.0 lib/atacama/contract.rb