lib/roda.rb in roda-2.26.0 vs lib/roda.rb in roda-2.27.0
- old
+ new
@@ -685,15 +685,35 @@
matched
end
end
+ # Match the given class. Currently, the following classes
+ # are supported by default:
+ # Integer :: Match an integer segment, yielding result to block as an integer
+ # String :: Match any non-empty segment, yielding result to block as a string
+ def _match_class(klass)
+ meth = :"_match_class_#{klass}"
+ if respond_to?(meth, true)
+ send(meth)
+ else
+ unsupported_matcher(klass)
+ end
+ end
+
# Match the given hash if all hash matchers match.
def _match_hash(hash)
hash.all?{|k,v| send("match_#{k}", v)}
end
+ # Match integer segment, and yield resulting value as an
+ # integer.
+ def _match_class_Integer
+ consume(/\A\/(\d+)(?=\/|\z)/){|i| [i.to_i]}
+ end
+
+ # Match only if all of the arguments in the given array match.
# Match the given regexp exactly if it matches a full segment.
def _match_regexp(re)
consume(self.class.cached_matcher(re){re})
end
@@ -723,11 +743,11 @@
end
end
end
# Match the given symbol if any segment matches.
- def _match_symbol(sym)
+ def _match_symbol(sym=nil)
rp = @remaining_path
if rp[0, 1] == SLASH
if last = rp.index('/', 1)
if last > 1
@captures << rp[1, last-1]
@@ -738,10 +758,13 @@
@remaining_path = EMPTY_STRING
end
end
end
+ # Match any nonempty segment. This should be called without an argument.
+ alias _match_class_String _match_symbol
+
# The regular expression to use for matching symbols. By default, any non-empty
# segment matches.
def _match_symbol_regexp(s)
SEGMENT
end
@@ -789,11 +812,13 @@
# SCRIPT_NAME to include the matched path, removes the matched
# path from PATH_INFO, and updates captures with any regex captures.
def consume(pattern)
if matchdata = remaining_path.match(pattern)
@remaining_path = matchdata.post_match
- @captures.concat(matchdata.captures)
+ captures = matchdata.captures
+ captures = yield(*captures) if block_given?
+ @captures.concat(captures)
end
end
# The default path to use for redirects when a path is not given.
# For non-GET requests, redirects to the current path, which will
@@ -834,21 +859,23 @@
else
@remaining_path = path
false
end
end
-
+
# Attempt to match the argument to the given request, handling
# common ruby types.
def match(matcher)
case matcher
when String
_match_string(matcher)
- when Symbol
- _match_symbol(matcher)
+ when Class
+ _match_class(matcher)
when TERM
empty_path?
+ when Symbol
+ _match_symbol(matcher)
when Regexp
_match_regexp(matcher)
when Hash
_match_hash(matcher)
when Array
@@ -856,14 +883,11 @@
when Proc
matcher.call
when true, false, nil
matcher
else
- if roda_class.opts[:unsupported_matcher] == :raise
- raise RodaError, "unsupported matcher: #{matcher.inspect}"
- end
- matcher
+ unsupported_matcher(matcher)
end
end
# Match only if all of the arguments in the given array match.
def match_all(args)
@@ -882,9 +906,17 @@
# Whether string matchers are used verbatim, without handling
# placeholders via colons.
def placeholder_string_matcher?
!roda_class.opts[:verbatim_string_matcher]
+ end
+
+ # Handle an unsupported matcher.
+ def unsupported_matcher(matcher)
+ if roda_class.opts[:unsupported_matcher] == :raise
+ raise RodaError, "unsupported matcher: #{matcher.inspect}"
+ end
+ matcher
end
end
# Class methods for RodaResponse
module ResponseClassMethods