lib/cotton_tail/route.rb in cotton-tail-0.5.0 vs lib/cotton_tail/route.rb in cotton-tail-0.6.0
- old
+ new
@@ -1,36 +1,48 @@
# frozen_string_literal: true
module CottonTail
- # Route value object
- class Route
- attr_reader :pattern
-
+ # Route pattern matcher
+ class Route < SimpleDelegator
def initialize(pattern)
@pattern = pattern
+ super build_regex
end
- def match?(routing_key)
- return true if @pattern == routing_key
+ def extract_params(routing_key)
+ return {} unless match? routing_key
- regex.match? routing_key
+ match(routing_key).named_captures
end
- def to_s
- @pattern
+ def binding
+ segments.map(&:binding).join('.')
end
private
- def regex
- @regex ||= Regexp.new build_regex(@pattern)
+ def explode
+ @pattern.split('.').map(&RouteSegment.method(:new))
end
- def build_regex(pattern)
- [
- '^',
- pattern.gsub('*', '([^.]+)').gsub(/\.?#\.?/, '([^.]{0,}\.?)+'),
- '$'
- ].join
+ def collapse
+ segments.zip(separators).join
+ end
+
+ def segments
+ @segments ||= explode
+ end
+
+ def separators
+ separators = segments.each_with_index.map do |segment, idx|
+ [Regexp.escape('.')].tap do |sep|
+ sep << '?' if segment.hash? && idx.zero?
+ end
+ end
+ separators.map(&:join)[0..-2]
+ end
+
+ def build_regex
+ Regexp.new "^#{collapse}$"
end
end
end