Sha256: 22e802f02de3a587382e36500ec1e7e740a17ff435b5f7e4d94b08f23370dfd7

Contents?: true

Size: 1.42 KB

Versions: 2

Compression:

Stored size: 1.42 KB

Contents

require 'search_lingo/tokenizer'

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

    attr_reader :query

    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

    def scope
      @scope
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

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