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