class Tennpipes::PathRouter::Compiler

High performance engine for finding all routes which are matched with pattern

Attributes

regexps[R]

All regexps generated by recursive compiler

Public Class Methods

new(routes) click to toggle source

Constructs an instance of Tennpipes::PathRouter::Compiler

# File lib/tennpipes-base/path_router/compiler.rb, line 13
def initialize(routes)
  @routes = routes
end

Public Instance Methods

call_by_request(request) { |route, params| ... } click to toggle source

Calls routes by using request.

# File lib/tennpipes-base/path_router/compiler.rb, line 50
def call_by_request(request)
  rotation do |offset|
    pattern  = encode_default_external(request.path_info)
    if route = match?(offset, pattern)
      params = route.params_for(pattern, request.params)
      yield(route, params) if route.verb == request.request_method
      route
    end
  end
end
compile!() click to toggle source

Compiles all routes into regexps.

# File lib/tennpipes-base/path_router/compiler.rb, line 20
def compile!
  return if compiled?
  @regexps = @routes.map.with_index do |route, index|
    route.index = index
    /(?<_#{index}>#{route.matcher.to_regexp})/
  end
  @regexps = recursive_compile(@regexps)
  @compiled = true
end
compiled?() click to toggle source

Returns true if all routes has been compiled.

# File lib/tennpipes-base/path_router/compiler.rb, line 33
def compiled?
  !!@compiled
end
find_by(request_or_env) click to toggle source

Finds routes by using request or env.

# File lib/tennpipes-base/path_router/compiler.rb, line 40
def find_by(request_or_env)
  request = request_or_env.is_a?(Hash) ? Sinatra::Request.new(request_or_env) : request_or_env
  pattern = encode_default_external(request.path_info)
  verb    = request.request_method
  rotation { |offset| match?(offset, pattern) }.select { |route| route.verb == verb }
end
find_by_pattern(pattern) click to toggle source

Finds routes by using PATH_INFO.

# File lib/tennpipes-base/path_router/compiler.rb, line 64
def find_by_pattern(pattern)
  pattern = pattern.encode(Encoding.default_external)
  rotation { |offset| match?(offset, pattern) }
end

Private Instance Methods

encode_default_external(string) click to toggle source

Encode string with Encoding.default_external

# File lib/tennpipes-base/path_router/compiler.rb, line 105
def encode_default_external(string)
  string.encode(Encoding.default_external)
end
match?(offset, path) click to toggle source

Returns a instance of PathRouter::Route if path is matched with current regexp

# File lib/tennpipes-base/path_router/compiler.rb, line 74
def match?(offset, path)
  current_regexp = @regexps[offset]
  return unless current_regexp === path || current_regexp === path[0..-2]
  @routes[offset..-1].detect{ |route| Regexp.last_match["_#{route.index}"] }
end
recursive_compile(regexps, paths = []) click to toggle source

Compiles routes into regexp recursively.

# File lib/tennpipes-base/path_router/compiler.rb, line 95
def recursive_compile(regexps, paths = [])
  return paths if regexps.length.zero?
  paths << Regexp.union(regexps)
  regexps.shift
  recursive_compile(regexps, paths)
end
rotation(offset = 0) { |offset| ... } click to toggle source

Runs through all regexps to find routes.

# File lib/tennpipes-base/path_router/compiler.rb, line 83
def rotation(offset = 0)
  compile! unless compiled?
  loop.with_object([]) do |_, candidacies|
    return candidacies unless route = yield(offset)
    candidacies << route
    offset = route.index.next
  end
end