Sha256: 99b7ae19dae6f8ed11c91fb8abd0a97f3dc5e800c1104f9ab00cdd55cc59a728

Contents?: true

Size: 1.68 KB

Versions: 3

Compression:

Stored size: 1.68 KB

Contents

# frozen_string_literal: true

require "set"

module Dry
  module Events
    # Event filter
    #
    # A filter cherry-picks probes payload of events.
    # Events not matching the predicates don't fire callbacks.
    #
    # @api private
    class Filter
      NO_MATCH = Object.new.freeze

      # @!attribute [r] events
      #   @return [Array] A list of lambdas checking payloads
      attr_reader :checks

      # Create a new filter
      #
      # @param [Hash] filter Source filter
      #
      # @api private
      def initialize(filter)
        @checks = build_checks(filter)
      end

      # Test event payload against the checks
      #
      # @param [Hash] payload Event payload
      #
      # @api private
      def call(payload = EMPTY_HASH)
        checks.all? { |check| check.(payload) }
      end

      # Recursively build checks
      #
      # @api private
      def build_checks(filter, checks = EMPTY_ARRAY, keys = EMPTY_ARRAY)
        if filter.is_a?(Hash)
          filter.reduce(checks) do |cs, (key, value)|
            build_checks(value, cs, [*keys, key])
          end
        else
          [*checks, method(:compare).curry.(keys, predicate(filter))]
        end
      end

      # @api private
      def compare(path, predicate, payload)
        value = path.reduce(payload) do |acc, key|
          if acc.is_a?(Hash) && acc.key?(key)
            acc[key]
          else
            break NO_MATCH
          end
        end

        predicate.(value)
      end

      # @api private
      def predicate(value)
        case value
        when Proc then value
        when Array then value.method(:include?)
        else value.method(:==)
        end
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
dry-events-1.0.1 lib/dry/events/filter.rb
dry-events-1.0.0 lib/dry/events/filter.rb
dry-events-0.4.0 lib/dry/events/filter.rb