class Angus::Router
Constants
- PathPattern
- RE_TRAILING_SLASH
- Route
- SUPPORTED_HTTP_METHODS
- VERSION
Public Instance Methods
It registers block to be yielded at a given HTTP method and path.
@param [Symbol] m HTTP method (see SUPPORTED_HTTP_METHODS
) @param [String] path Url path @param [Proc] block The block that will be yielded when an incoming request matches the route
# File lib/angus/router.rb, line 60 def on(m, path, &block) path = path.gsub(RE_TRAILING_SLASH, '') unless SUPPORTED_HTTP_METHODS.include?(m) raise ArgumentError.new("Unsupported HTTP method #{m}") end route = Route.new(m.to_s.upcase, block, compile(path)) if route.params? dynamic_routes << route else static_routes << route end end
Calls the corresponding previously registered block.
When calling, the rack environment and the extracted path params are passed to the route block.
@param [Hash] env A Rack environment. (see rack.rubyforge.org/doc/SPEC.html)
@return The result of the block call
# File lib/angus/router.rb, line 84 def route(env) request = Rack::Request.new(env) path_info = request.path_info.gsub(RE_TRAILING_SLASH, '').squeeze('/') matched_route = match_route(env['REQUEST_METHOD'], path_info) match, route_block, path_param_names = matched_route unless match raise NotImplementedError, "No route found #{request.path_info}" end path_params = extract_params(match, path_param_names) whole_params = request.params.clone.merge!(path_params) whole_params = symbolize(whole_params) route_block.call(env, whole_params) end
Private Instance Methods
Returns a path pattern base on the given pattern.
@example compile('/users/:id')
=> PathPattern.new(/^\/users\/([^\/?#]+)$/, ['id']])
@param [String] Url path
@return [PathPattern]
# File lib/angus/router.rb, line 131 def compile(pattern) keys = [] pattern = pattern.to_str.squeeze('/') pattern.gsub!(/[^\?\%\\\/\:\*\w]/) { |c| encoded(c) } pattern.gsub!(/(:\w+)/) do |match| keys << $1[1..-1] "([^/?#]+)" end PathPattern.new(/^#{pattern}$/, keys) end
# File lib/angus/router.rb, line 115 def dynamic_routes @dynamic_routes ||= [] end
Escapes a char for uri regex matching.
@param [String] char
@return [String]
# File lib/angus/router.rb, line 149 def encoded(char) enc = URI.escape(char) enc = "(?:#{Regexp.escape enc}|#{URI.escape char, /./})" if enc == char enc = "(?:#{enc}|#{encoded('+')})" if char == " " enc end
Extracts matched values from the given match.
Assoaciates each match to the corresponding key.
@param [MatchData] match @param [Array] keys
@return [Hash] A hash containing extracted key / values
# File lib/angus/router.rb, line 183 def extract_params(match, keys) hash = {} captures = match.captures keys.each_with_index do |k, i| hash[k] = captures[i] end hash end
Returns regexp, block and path param names according to the route that matches the given method and path.
@param [String] method HTTP method @param [String] path Url path
@return [regexp, route_block, path_param_names]
# File lib/angus/router.rb, line 163 def match_route(method, path) [static_routes, dynamic_routes].each do |routes| routes.each do |route| if method == route.method && match = route.match(path) return [match, route.proc, route.param_names] end end end nil end
# File lib/angus/router.rb, line 119 def static_routes @static_routes ||= [] end
Returns a shallow copy with keys as symbols of hash.
@param [Hash] hash
@return [Hash]
# File lib/angus/router.rb, line 109 def symbolize(hash) Hash[ hash.map { |k, v| [k.to_sym, v] } ] end