Sha256: 1deaef2103bbe97b5c8c503daca88287a21f27cbd1a8041b97d25054b361e0ea

Contents?: true

Size: 1.32 KB

Versions: 1

Compression:

Stored size: 1.32 KB

Contents

# frozen_string_literal: true

require "ostruct"

module Fear
  module Extractor
    # @abstract abstract matcher to inherit from.
    class Matcher < OpenStruct
      autoload :And, "fear/extractor/matcher/and"

      EMPTY_HASH = {}.freeze
      EMPTY_ARRAY = [].freeze

      # @param node [Fear::Extractor::Grammar::Node]
      def initialize(node:, **attributes)
        @input = node.input
        @input_position = node.interval.first
        super(attributes)
      end
      attr_reader :input_position, :input
      private :input
      private :input_position

      def call(arg)
        call_or_else(arg, &PartialFunction::EMPTY)
      end

      def and(other)
        And.new(self, other)
      end

      # @param arg [any]
      # @yield [arg] if function not defined
      def call_or_else(arg)
        if defined_at?(arg)
          bindings(arg)
        else
          yield arg
        end
      end

      # Shows why matcher has failed. Use it for debugging.
      # @example
      #   Fear['[1, 2, _]'].failure_reason([1, 3, 4])
      #   # it will show that the second element hasn't match
      #
      def failure_reason(other)
        if defined_at?(other)
          Fear.none
        else
          Fear.some("Expected `#{other.inspect}` to match:\n#{input}\n#{"~" * input_position}^")
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
fear-1.1.0 lib/fear/extractor/matcher.rb