class Utopia::Path::Matcher
Performs structured, efficient, matches against {Path} instances. Supports regular expressions, type-casts and constants. @example
path = Utopia::Path['users/20/edit'] matcher = Utopia::Path::Matcher[users: /users/, id: Integer, action: String] match_data = matcher.match(path)
Public Class Methods
[](patterns)
click to toggle source
# File lib/utopia/path/matcher.rb, line 60 def self.[](patterns) self.new(patterns) end
new(patterns = [])
click to toggle source
@param patterns [Hash<Symbol,Pattern>] An ordered list of things to match.
# File lib/utopia/path/matcher.rb, line 56 def initialize(patterns = []) @patterns = patterns end
Public Instance Methods
coerce(klass, value)
click to toggle source
# File lib/utopia/path/matcher.rb, line 64 def coerce(klass, value) if klass == Integer Integer(value) elsif klass == Float Float(value) elsif klass == String value.to_s else klass.new(value) end rescue return nil end
match(path)
click to toggle source
This is a path prefix matching algorithm. The pattern is an array of String, Symbol, Regexp, or nil. The path is an array of String.
# File lib/utopia/path/matcher.rb, line 79 def match(path) components = path.to_a # Can't possibly match if not enough components: return nil if components.size < @patterns.size named_parts = {} # Try to match each component against the pattern: @patterns.each_with_index do |(key, pattern), index| component = components[index] if pattern.is_a? Class return nil unless value = coerce(pattern, component) named_parts[key] = value elsif pattern if result = pattern.match(component) named_parts[key] = result else # Couldn't match: return nil end else # Ignore this part: named_parts[key] = component end end return MatchData.new(named_parts, components[@patterns.size..-1]) end