Sha256: 0eeeb32e7d3e16d63cb487f6b6c654ed0afaf5a3080e9bd2ef8bab9be18c1296

Contents?: true

Size: 1.43 KB

Versions: 4

Compression:

Stored size: 1.43 KB

Contents

# frozen_string_literal: true

require 'dry/core/class_attributes'
require 'dry/effects/frame'

module Dry
  module Effects
    class Provider
      module ClassInterface
        def self.extended(base)
          base.instance_exec do
            defines :type

            @mutex = ::Mutex.new
            @effects = ::Hash.new do |es, type|
              @mutex.synchronize do
                es.fetch(type) do
                  es[type] = Class.new(Provider).tap do |provider|
                    provider.type type
                  end
                end
              end
            end
          end
        end

        include Core::ClassAttributes

        attr_reader :effects

        def [](type)
          if self < Provider
            Provider.effects.fetch(type) do
              Provider.effects[type] = ::Class.new(self).tap do |subclass|
                subclass.type type
              end
            end
          else
            @effects[type]
          end
        end

        def mixin(*as, **kw)
          handle_method = handle_method(*as, **kw)

          provider = new(*as, **kw).freeze
          frame = Frame.new(provider)

          ::Module.new do
            define_method(handle_method) do |*args, &block|
              frame.(*args, &block)
            end
          end
        end

        def handle_method(*, as: Undefined, **)
          Undefined.default(as) { :"with_#{type}" }
        end
      end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
dry-effects-0.1.5 lib/dry/effects/provider/class_interface.rb
dry-effects-0.1.4 lib/dry/effects/provider/class_interface.rb
dry-effects-0.1.3 lib/dry/effects/provider/class_interface.rb
dry-effects-0.1.2 lib/dry/effects/provider/class_interface.rb