From eb09313a38aecf7e7cc5292a2fd1c7845609ff1c Mon Sep 17 00:00:00 2001 From: mms Date: Thu, 7 Nov 2024 23:17:14 +0100 Subject: feat: hash filters --- lib/some/messages.rb | 53 +++++++++++++++++++++++++++++++++++++++------------ spec/messages_spec.rb | 18 +++++++++++++++++ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/lib/some/messages.rb b/lib/some/messages.rb index 78c36a3..264fac6 100644 --- a/lib/some/messages.rb +++ b/lib/some/messages.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'pry' module Some class Messages AND_CONJUCTION = :and @@ -9,9 +10,37 @@ module Some Token = Struct.new(:id, :conjuction, :field, :value) do def to_query conjuction_to_use = id > 1 ? conjuction : '' - return unless field == :direct + return "#{conjuction_to_use} (#{value})" if field == :direct - "#{conjuction_to_use} (#{value})" + "#{conjuction_to_use} (#{field}:#{value})" + end + end + + TokenGroup = Struct.new(:conjuction, :tokens) do + def initialize(*) + super + @token_count = 0 + end + + def to_query + "(#{tokens.flat_map(&:to_query).join(' ')})" + end + + def push_token(field, value) + if value.is_a? String + tokens.push(Token.new(next_token_id, conjuction, field, value)) + elsif value.is_a? Array + group = TokenGroup.new(OR_CONJUCTION, []) + value.each do |val| + group.push_token(field, val) + end + tokens.push group + + end + end + + def next_token_id + @token_count += 1 end end @@ -37,18 +66,10 @@ module Some case params when String add_filter_from_string(params) + when Hash + add_filter_from_hash(params) end - # query << params.map do |key, value| - # unless value.is_a? Array - # [current_conjuction, key, value.to_sym] - # else - # - # [current_conjuction, - # value.map { |subarg| [OR_CONJUCTION, key, subarg] }] - # end - # end - # self end @@ -56,6 +77,14 @@ module Some @query << Token.new(next_token_id, current_conjuction, :direct, string) end + def add_filter_from_hash(hash) + group = TokenGroup.new(AND_CONJUCTION, []) + hash.each do |key, value| + group.push_token(key, value) + end + @query << group + end + def query_string query.map(&:to_query).join(' ') end diff --git a/spec/messages_spec.rb b/spec/messages_spec.rb index 5998fd1..de8b393 100644 --- a/spec/messages_spec.rb +++ b/spec/messages_spec.rb @@ -35,4 +35,22 @@ RSpec.describe Some::Messages do .to eq(' (from:baltar@battlestar.com) or (ship:galactica) and (hair:long)') } end + + describe 'hash filters' do + context 'with singular values' do + it { expect(subject.filter(from: 'baltar@battlestar.com').query_string).to eq('( (from:baltar@battlestar.com))') } + + it { + expect(subject.filter(from: 'baltar@battlestar.com', ship: 'galactica').query_string) + .to eq('( (from:baltar@battlestar.com) and (ship:galactica))') + } + end + + context 'with set of values' do + it { + expect(subject.filter(from: ['baltar@battlestar.com', + 'adama@battestar.com']).query_string).to eq('(( (from:baltar@battlestar.com) or (from:adama@battestar.com)))') + } + end + end end -- cgit v1.2.3