lib/hx/path.rb in hx-0.8.2 vs lib/hx/path.rb in hx-0.8.3

- old
+ new

@@ -23,15 +23,10 @@ module Hx module Path module Selector - def prefix ; "" ; end - def suffix ; "" ; end - def regexp ; nil ; end - def remaining_suffix(prefix_consumed) ; suffix ; end - def accept?(path) raise NotImplementedError, "#{self.class}#accept? not implemented" end def |(other) @@ -47,41 +42,29 @@ end end class All include Selector - - REGEXP = Regexp.new("^.*$") - - def regexp ; REGEXP ; end def accept?(path) ; true ; end end ALL = All.new -class Literal +class Pattern include Selector - attr_reader :value - alias prefix value - - def initialize(value) - @value = value - @regexp = nil + def initialize(tokens) + @regexp = Regexp.new("^#{tokens.map { |token| + case token + when :doublestar; '.*' + when :star; '[^/]*' + else; Regexp.quote(token) + end + }}$") end - def remaining_suffix(prefix_consumed) - @value[prefix_consumed..-1] - end - - def regexp - @regexp ||= Regexp.new("^#{Regexp.quote(@value)}$") - end - - def accept?(path) - @value == path - end + def accept?(path) ; !!(path =~ @regexp) ; end end def self.parse_pattern(pattern_string) tokens = [] pattern_string.scan(/(\*\*?|[^*]+)/) do |token,| @@ -89,107 +72,48 @@ when "**"; :doublestar when "*"; :star else; token end end - prefix = tokens.first - if tokens.size == 1 and String === prefix - Literal.new(prefix) - else - prefix = "" unless String === prefix - suffix = tokens.last - suffix = "" unless String === suffix - regexp = Regexp.new("^#{tokens.map { |token| - case token - when :doublestar; '.*' - when :star; '[^/]*' - else; Regexp.quote(token) - end - }}$") - Pattern.new(regexp, prefix, suffix) - end + Pattern.new(tokens) end def self.literal(literal_string) - Literal.new(literal_string) + Pattern.new([literal_string]) end -class Pattern - include Selector - - attr_reader :prefix - attr_reader :suffix - attr_reader :regexp - - def initialize(regexp, prefix, suffix) - @regexp = regexp - @prefix = prefix - @suffix = suffix - end - - def accept?(path) - !!(@regexp.match(path)) - end -end - module Connective include Selector - attr_reader :prefix - attr_reader :suffix - def initialize(*selectors) @selectors = selectors - prefixes = selectors.map { |s| s.prefix } - prefix_length = (prefixes.first || "").length - prefixes.each_cons(2) do |a, b| - prefix_length.downto(0) do |length| - prefix_length = length - break if a[0...length] == b[0...length] - end - end - @prefix = prefixes.first[0...prefix_length] - suffixes = selectors.map { |s| s.remaining_suffix(prefix_length) } - suffix_length = (suffixes.first || "").length - suffixes.each_cons(2) do |a, b| - suffix_length.downto(0) do |length| - suffix_length = length - break if a[-length..-1] == b[-length..-1] - end - end - @suffix = suffixes.first[-suffix_length..-1] end end class Conjunction include Connective + def self.new(*selectors) + if selectors.any? { |s| All === s } + selectors.reject! { |s| All === s } + case selectors.size + when 0; return ALL + when 1; return selectors.first + end + end + super(*selectors) + end + def accept?(path) @selectors.all? { |s| s.accept? path } end end class Disjunction include Connective - attr_reader :regexp - - def initialize(*selectors) - super - regexps = @selectors.map { |s| s.regexp } - if regexps.all? - @regexp = Regexp.union(*regexps) - else - @regexp = nil - end - end - def accept?(path) - if @regexp - !!@regexp.match(path) - else - @selectors.any? { |s| s.accept? path } - end + @selectors.any? { |s| s.accept? path } end end class Negation include Selector