Class: Flon::Router

Inherits:
Object
  • Object
show all
Defined in:
lib/flon/router.rb

Overview

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

Defined Under Namespace

Classes: Match

Constant Summary collapse

VALID_HTTP_METHODS =

The HTTP methods as symbols that this router will handle.

%i[get post put delete patch].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRouter

Creates a new Router with an empty route set.



28
29
30
# File 'lib/flon/router.rb', line 28

def initialize
  @routes = []
end

Instance Attribute Details

#routesArray<Mustermann::Sinatra, Hash{Symbol => Object}> (readonly)

Returns the current route set.

Returns:

  • (Array<Mustermann::Sinatra, Hash{Symbol => Object}>)

    the current route set



24
25
26
# File 'lib/flon/router.rb', line 24

def routes
  @routes
end

Instance Method Details

#add_route(method, path, action) ⇒ self

Adds a route to this router’s route set.

Parameters:

  • method (Symbol)

    the method to use

  • path (String)

    the path to use

  • action (Object)

    the action to use

Returns:

Raises:

  • (ArgumentError)

    if method is not a valid HTTP method or the given route is already registered



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 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) ⇒ RouteMatch, ...

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

Parameters:

  • method (Symbol)

    the HTTP method to match against

  • path (String)

    the path to match against

Returns:

  • (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



64
65
66
67
68
69
70
71
72
73
74
75
76
# 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) ⇒ Boolean

Returns true if this router has a route with that method and path in its route set, false otherwise.

Returns:

  • (Boolean)

    true if this router has a route with that method and path in its route set, false otherwise



80
81
82
# 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