class Flon::Router

Handles a set of routes mapped to actions. Note that the Router API is mainly for private Flon use.

Constants

Match

A route's match is encapsulated in this struct. {#action} has the action associated with the route matched against and {#params} has the parameters hash.

@!attribute [r] action

@return the route's action

@!attribute [r] params

@return [Hash{Symbol => Object}] the route's bound parameters
VALID_HTTP_METHODS

The HTTP methods as symbols that this router will handle.

Attributes

routes[R]

@return [Array<Mustermann::Sinatra, Hash{Symbol => Object}>] the current route set

Public Class Methods

new() click to toggle source

Creates a new Router with an empty route set. @return [Router] the newly constructed object

# File lib/flon/router.rb, line 28
def initialize
  @routes = []
end

Public Instance Methods

add_route(method, path, action) click to toggle source

Adds a route to this router's route set.

@param [Symbol] method the method to use @param [String] path the path to use @param [Object] action the action to use @return [self] this {Router} @raise [ArgumentError] if method is not a valid HTTP method or the given

route is already registered
# File lib/flon/router.rb, line 40
def add_route(method, path, action) # rubocop:disable Metrics/MethodLength
  raise ArgumentError, "#{method} is not a valid HTTP method" unless valid_method?(method)
  raise ArgumentError, "route #{method.upcase} #{path} is already registered" if routing_to?(method, path)

  route = @routes.find { |it| it[0].to_s == path }
  if route
    route[1][method] = action
  else
    route = [Mustermann::Sinatra.new(path), { method => action }]
    @routes << route
  end

  route[1][:head] = action if method == :get

  self
end
match(method, path) click to toggle source

Matches a method and path against this router's route set.

@param [Symbol] method the HTTP method to match against @param [String] path the path to match against @return [RouteMatch, :bad_path, :bad_method] if successful, a RouteMatch;

if not, :bad_method if the path exists but not bound to that HTTP
method, :bad_path otherwise
# File lib/flon/router.rb, line 64
def match(method, path)
  @routes.each do |route|
    params = route[0].params(path)
    next unless params

    action = route[1][method]
    return :bad_method unless action

    return Match.new(action, params.transform_keys(&:to_sym))
  end

  :bad_path
end
routing_to?(method, path) click to toggle source

@return [Boolean] true if this router has a route with that method and

path in its route set, false otherwise
# File lib/flon/router.rb, line 80
def routing_to?(method, path)
  @routes.any? { |it| it[0].to_s == path && it[1].include?(method) }
end

Private Instance Methods

valid_method?(method) click to toggle source
# File lib/flon/router.rb, line 86
def valid_method?(method)
  VALID_HTTP_METHODS.include?(method)
end