Class: Takagi::Router::RouteMatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/takagi/router/route_matcher.rb,
sig/takagi/router/route_matcher.rbs

Overview

Handles dynamic route matching with parameter extraction.

Extracted from Router to follow Single Responsibility Principle. Manages matching URL patterns with dynamic segments (e.g., /users/:id) and extracting parameters from matched routes.

Instance Method Summary collapse

Constructor Details

#initialize(logger) ⇒ RouteMatcher

Returns a new instance of RouteMatcher.

Parameters:

  • logger (Logger)

    Logger instance for debugging



12
13
14
# File 'lib/takagi/router/route_matcher.rb', line 12

def initialize(logger)
  @logger = logger
end

Instance Method Details

#extract_dynamic_params(route_path, path) ⇒ Hash?

Extracts dynamic parameters from a route pattern

Compares route pattern (e.g., /users/:id) with actual path (e.g., /users/123) and extracts parameter values.

Parameters:

  • route_path (String)

    Route pattern with :param segments

  • path (String)

    Actual request path

Returns:

  • (Hash, nil)

    Extracted parameters or nil if no match



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/takagi/router/route_matcher.rb', line 61

def extract_dynamic_params(route_path, path)
  route_parts = route_path.split('/')
  path_parts = path.split('/')
  return unless route_parts.length == path_parts.length

  params = {}
  matched = true

  route_parts.each_with_index do |part, index|
    if part.start_with?(':')
      params[part[1..].to_sym] = path_parts[index]
    elsif part != path_parts[index]
      @logger.debug "No Match found! Params: #{params.inspect} to #{path}"
      matched = false
      break
    end
  end

  matched ? params : nil
end

#locate_dynamic_route(routes, method, path) ⇒ Array(RouteEntry, Hash)?

Locates a dynamic route by iterating through all routes

Parameters:

  • routes (Hash)

    All registered routes

  • method (String)

    HTTP method to match

  • path (String)

    Request path to match

Returns:

  • (Array(RouteEntry, Hash), nil)

    Matched entry and params, or nil



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/takagi/router/route_matcher.rb', line 38

def locate_dynamic_route(routes, method, path)
  routes.each_value do |entry|
    route_method = entry.method
    route_path = entry.path
    next unless route_method == method

    params = extract_dynamic_params(route_path, path)
    next unless params

    @logger.debug "Match found! Params: #{params.inspect}"
    return [entry, params]
  end
  nil
end

#match(routes, method, path) ⇒ Array(RouteEntry, Hash), Array(nil, Hash)

Matches dynamic routes that contain parameters (e.g., /users/:id)

Parameters:

  • routes (Hash)

    Map of route keys to RouteEntry objects

  • method (String)

    HTTP method

  • path (String)

    Request path

Returns:

  • (Array(RouteEntry, Hash), Array(nil, Hash))

    Matched route entry and parameters, or [nil, {}]



22
23
24
25
26
27
28
# File 'lib/takagi/router/route_matcher.rb', line 22

def match(routes, method, path)
  matched_route = locate_dynamic_route(routes, method, path)
  return matched_route if matched_route

  @logger.debug 'No route matched!'
  [nil, {}]
end