diff options
Diffstat (limited to 'lib/osugiru/messages.rb')
-rw-r--r-- | lib/osugiru/messages.rb | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/lib/osugiru/messages.rb b/lib/osugiru/messages.rb new file mode 100644 index 0000000..4af19b6 --- /dev/null +++ b/lib/osugiru/messages.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'pry' +module Osugiru + class Messages + AND_CONJUCTION = :and + OR_CONJUCTION = :or + DEFAULT_CONJUCTION = AND_CONJUCTION + + Token = Struct.new(:conjuction, :field, :value, :messages) do + def to_query + conjuction_to_use = messages.next_token_id > 1 ? conjuction : '' + return "#{conjuction_to_use} (#{value})" if field == :direct + + "#{conjuction_to_use} (#{field}:#{value})" + end + end + + TokenGroup = Struct.new(:conjuction, :tokens, :messages) do + def initialize(*) + super + end + + def to_query + tokens.flat_map(&:to_query).join(' ').to_s + end + + def push_token(field, value) + if value.is_a? String + tokens.push(Token.new(conjuction, field, value, messages)) + elsif value.is_a? Array + group = TokenGroup.new(OR_CONJUCTION, [], messages) + value.each do |val| + group.push_token(field, val) + end + tokens.push group + + end + end + + def next_token_id + @token_count += 1 + end + end + + attr_accessor :query, :current_conjuction, :token_count + attr_reader :db + + def initialize(db:) + @db = db + @query = [] + @current_conjuction = AND_CONJUCTION + @token_count = 0 + end + + def or + @current_conjuction = OR_CONJUCTION + self + end + + def and + @current_conjuction = AND_CONJUCTION + self + end + + def filter(params) + case params + when String + add_filter_from_string(params) + when Hash + add_filter_from_hash(params) + end + + self + end + + def each + db.search_messages(query_string).each do |msg| + yield(Message.new(msg: msg)) + end + end + + def add_filter_from_string(string) + @query << Token.new(current_conjuction, :direct, string, self) + end + + def add_filter_from_hash(hash) + group = TokenGroup.new(current_conjuction, [], self) + hash.each do |key, value| + group.push_token(key, value) + end + @query << group + end + + def query_string + query.map(&:to_query).join(' ') + end + + def next_token_id + @token_count += 1 + end + end +end |