summaryrefslogtreecommitdiff
path: root/fake-service/lib/pixelated_service/search.rb
diff options
context:
space:
mode:
Diffstat (limited to 'fake-service/lib/pixelated_service/search.rb')
-rw-r--r--fake-service/lib/pixelated_service/search.rb133
1 files changed, 0 insertions, 133 deletions
diff --git a/fake-service/lib/pixelated_service/search.rb b/fake-service/lib/pixelated_service/search.rb
deleted file mode 100644
index e8f9d9fd..00000000
--- a/fake-service/lib/pixelated_service/search.rb
+++ /dev/null
@@ -1,133 +0,0 @@
-# Syntax notes for search:
-# you can put a - in front of any search term to negate it
-# you can scope a search by putting a name of a scope, a colon and then the search term WITHOUT a space.
-# scoping will allow you to search for more things than otherwise available
-# an unknown scope name will be assumed to be a header to search
-# you can surround a search term in quotes to search for the whole thing
-# multiple search terms will be ANDed together
-# you can OR things by using the keyword OR/or - if you have it without parens, you will or the whole left with the whole right, until we find another or.
-# if you use parenthesis, you can group together terms
-# search in:_default_, in:all, in:trash, in:sent, in:drafts will only work for the WHOLE search. You can do a negation on a scoped search if it's in:trash, in:sent or in:drafts, but not for in:all
-
-module PixelatedService
- class Search
- def initialize(q)
- if q
- @qtree, @search_scope = Search.compile(q)
- else
- @qtree, @search_scope = TrueMatch.new, PixelatedService::MailScopeFilter::Default
- end
- end
-
- def restrict(input)
- @search_scope.new(input).select do |mm|
- @qtree.match?(mm)
- end
- end
-
- REGEXP_DQUOTED = /"[^"]*"/
- REGEXP_SQUOTED = /'[^']*'/
- REGEXP_SCOPE = /\w+:(".*?"|'.*?'|[^\s\)]+)/
- REGEXP_OTHER = /[^\s\)]+/
-
- def self.scan_literal(qs)
- if qs.check(REGEXP_DQUOTED)
- StringMatch.new(qs.scan(REGEXP_DQUOTED), true)
- elsif qs.check(REGEXP_SQUOTED)
- StringMatch.new(qs.scan(REGEXP_SQUOTED), true)
- elsif qs.check(REGEXP_OTHER)
- StringMatch.new(qs.scan(REGEXP_OTHER))
- end
- end
-
- def self.combine_search_scopes(l, r)
- l + r
- end
-
- def self.compile(q, qs = StringScanner.new(q))
- qtree = AndMatch.new
- search_scope = PixelatedService::MailScopeFilter::Default
- until qs.eos?
- if qs.check(/\)/)
- qs.scan(/\)/)
- return optimized(qtree), search_scope
- end
-
- negated = false
- if qs.check(/-/)
- negated = true
- qs.scan(/-/)
- end
-
- if qs.check(/or/i)
- qs.scan(/or/i)
- left = qtree
- qtree = OrMatch.new(left, AndMatch.new)
- else
- res =
- if qs.check(/\(/)
- qs.scan(/\(/)
- v, sc = compile(q, qs)
- search_scope = search_scope + sc
- v
- elsif qs.check(REGEXP_DQUOTED)
- StringMatch.new(qs.scan(REGEXP_DQUOTED), true)
- elsif qs.check(REGEXP_SQUOTED)
- StringMatch.new(qs.scan(REGEXP_SQUOTED), true)
- elsif qs.check(REGEXP_SCOPE)
- scope = qs.scan(/\w+/)
- qs.scan(/:/)
- rest_node = scan_literal(qs)
- v = ScopeMatch.new(scope, rest_node)
- if v.is_search_scope? && !negated
- search_scope = search_scope + v.search_scope
- TrueMatch.new
- else
- v
- end
- elsif qs.check(REGEXP_OTHER)
- StringMatch.new(qs.scan(REGEXP_OTHER))
- end
- res = NegateMatch.new(res) if negated
- qtree << res
- end
-
- qs.scan(/\s+/)
- end
- return optimized(qtree), search_scope
- end
-
- def self.optimized(tree)
- case tree
- when AndMatch
- data = tree.data.reject { |d| TrueMatch === d }
- if data.length == 1
- optimized(data.first)
- else
- AndMatch.new(data.map { |n| optimized(n)} )
- end
- when OrMatch
- if tree.right.is_a?(AndMatch) && tree.right.data.empty?
- optimized(tree.left)
- else
- OrMatch.new(optimized(tree.left), optimized(tree.right))
- end
- when NegateMatch
- if tree.data.is_a?(NegateMatch)
- optimized(tree.data.data)
- else
- NegateMatch.new(optimized(tree.data))
- end
- else
- tree
- end
- end
- end
-end
-
-require 'pixelated_service/search/string_match'
-require 'pixelated_service/search/scope_match'
-require 'pixelated_service/search/negate_match'
-require 'pixelated_service/search/and_match'
-require 'pixelated_service/search/or_match'
-require 'pixelated_service/search/true_match'