Sha256: b1d5d95fbc4f4ad5a158999efe659ba9bb77b23b15454381b08745de46102955

Contents?: true

Size: 1.17 KB

Versions: 7

Compression:

Stored size: 1.17 KB

Contents

# frozen_string_literal: true

module BusinessPipeline
  module Hooks
    def self.included(base)
      base.class_eval do
        extend ClassMethods
      end
    end

    module ClassMethods
      def add_hooks(*new_hooks, type: __callee__, &block)
        hooks[type] += [*new_hooks, block].compact.map do |hook|
          hook.respond_to?(:new) ? hook.new : hook
        end
      end
      alias_method :after, :add_hooks
      alias_method :around, :add_hooks
      alias_method :before, :add_hooks

      def hooks
        @hooks ||= { after: [], around: [], before: [] }
      end
    end

    private def run_around_hooks(&block)
      around_hooks = self.class.hooks[:around]

      around_hooks
        .reverse
        .inject(block) { |chain, hook| proc { run_hook(hook, chain) } }
        .call
    end

    private def with_hooks
      run_around_hooks do
        run_hooks :before
        yield
        run_hooks :after
      end
    end

    private def run_hooks(type)
      self.class.hooks[type].each { |hook| run_hook(hook) }
    end

    private def run_hook(hook, *args)
      hook = method(hook) if hook.is_a?(Symbol)
      hook.call(*args, context, config)
    end
  end
end

Version data entries

7 entries across 7 versions & 1 rubygems

Version Path
business_pipeline-0.3.1 lib/business_pipeline/hooks.rb
business_pipeline-0.3.0 lib/business_pipeline/hooks.rb
business_pipeline-0.2.0 lib/business_pipeline/hooks.rb
business_pipeline-0.1.3 lib/business_pipeline/hooks.rb
business_pipeline-0.1.2 lib/business_pipeline/hooks.rb
business_pipeline-0.1.1 lib/business_pipeline/hooks.rb
business_pipeline-0.1.0 lib/business_pipeline/hooks.rb