Sha256: dd12e4d4b0fb255ad64bb228c4f9c9e6f03191231688ba230213e297e697523b

Contents?: true

Size: 1.39 KB

Versions: 1

Compression:

Stored size: 1.39 KB

Contents

require 'search_lingo/tokenizer'

module SearchLingo
  class AbstractSearch
    def initialize(query, scope)
      @query = query || ''
      @scope = scope
    end

    attr_reader :query, :scope

    def self.parsers
      @parsers ||= []
    end

    def self.parser(callable = nil, &block)
      unless callable || block_given?
        raise ArgumentError, 'parse must be called with callable or block'
      end
      if callable && block_given?
        warn "WARNING: parse called with callable and block (#{caller.first}"
      end

      parsers << (callable || block)
    end

    def parsers
      self.class.parsers
    end

    def results
      @results ||= conditions.inject(scope) do |query, condition|
        query.public_send(*condition)
      end
    end

    def conditions
      tokenizer.inject([]) do |conditions, token|
        conditions << catch(:match) do
          parse token
          if token.compound?
            token = tokenizer.simplify
            parse token
          end
          default_parse token
        end
      end
    end

    def tokenizer
      @tokenizer ||= Tokenizer.new query
    end

    def parse(token)
      parsers.each do |parser|
        result = parser.call token
        throw :match, result if result
      end
    end

    def default_parse(token)
      raise NotImplementedError,
        "#default_parse must be implemented by #{self.class}"
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
search_lingo-1.0.0.beta3 lib/search_lingo/abstract_search.rb