lib/roda.rb in roda-2.11.0 vs lib/roda.rb in roda-2.12.0

- old
+ new

@@ -324,10 +324,11 @@ PATH_INFO = "PATH_INFO".freeze SCRIPT_NAME = "SCRIPT_NAME".freeze REQUEST_METHOD = "REQUEST_METHOD".freeze EMPTY_STRING = "".freeze SLASH = "/".freeze + COLON = ":".freeze SEGMENT = "([^\\/]+)".freeze TERM_INSPECT = "TERM".freeze GET_REQUEST_METHOD = 'GET'.freeze SESSION_KEY = 'rack.session'.freeze @@ -674,16 +675,47 @@ # Match the given string to the request path. Regexp escapes the # string so that regexp metacharacters are not matched, and recognizes # colon tokens for placeholders. def _match_string(str) - consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}}) + if str.index(COLON) + consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}}) + else + rp = @remaining_path + if rp.start_with?("/#{str}") + last = str.length + 1 + case rp[last] + when SLASH + @remaining_path = rp[last, rp.length] + when nil + @remaining_path = EMPTY_STRING + when Integer + # :nocov: + # Ruby 1.8 support + if rp[last].chr == SLASH + @remaining_path = rp[last, rp.length] + end + # :nocov: + end + end + end end # Match the given symbol if any segment matches. def _match_symbol(sym) - consume(self.class.cached_matcher(sym){_match_symbol_regexp(sym)}) + rp = @remaining_path + if rp[0, 1] == SLASH + if last = rp.index('/', 1) + if last > 1 + @captures << rp[1, last-1] + @remaining_path = rp[last, rp.length] + end + elsif rp.length > 1 + @captures << rp[1,rp.length] + @remaining_path = EMPTY_STRING + end + end end # The regular expression to use for matching symbols. By default, any non-empty # segment matches. def _match_symbol_regexp(s) @@ -758,28 +790,30 @@ path = @remaining_path # For every block, we make sure to reset captures so that # nesting matchers won't mess with each other's captures. @captures.clear - return unless match_all(args) - block_result(yield(*captures)) - throw :halt, response.finish - ensure - @remaining_path = path + if match_all(args) + block_result(yield(*captures)) + throw :halt, response.finish + 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 Regexp - _match_regexp(matcher) when Symbol _match_symbol(matcher) when TERM empty_path? + when Regexp + _match_regexp(matcher) when Hash _match_hash(matcher) when Array _match_array(matcher) when Proc