Class: Rain::Trie

Inherits:
Object
  • Object
show all
Includes:
LowType
Defined in:
lib/router/trie.rb

Constant Summary collapse

PARAM_DELIMITERS =
['/', ':'].freeze
ARG_DELIMITERS =
['/'].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTrie

Returns a new instance of Trie.



16
17
18
# File 'lib/router/trie.rb', line 16

def initialize
  @root_node = TrieNode.new
end

Instance Attribute Details

#root_nodeObject (readonly)

Returns the value of attribute root_node.



14
15
16
# File 'lib/router/trie.rb', line 14

def root_node
  @root_node
end

Instance Method Details

#match(path:, current_node: @root_node, current_index: 0, params: {}) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/router/trie.rb', line 42

def match(path:, current_node: @root_node, current_index: 0, params: {})
  return [] if (key = path[current_index]).nil?

  route_events = []

  # Static request path segment.
  if (child_node = current_node.child(key:))
    route_events << route_event(next_index: current_index + 1, params:, path:, route: child_node.route) if child_node.route
    route_events = [*route_events, *match(path:, current_node: child_node, current_index: current_index + 1, params:)]
  end

  # Dynamic request path segment.
  current_node.params.each do |param|
    child_node = current_node.child(key: param)

    arg, next_index = capture_arg(arg_start_index: current_index, path:)
    params[param.delete_prefix(':').to_sym] = arg

    route_events << route_event(next_index:, params:, path:, route: child_node.route) if child_node.route
    route_events = [*route_events, *match(path:, current_node: child_node, current_index: next_index, params:)]
  end

  route_events
end

#merge(route:, current_node: @root_node, current_index: 0) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/router/trie.rb', line 24

def merge(route:, current_node: @root_node, current_index: 0)
  path = route.path

  while current_index < path.length
    key = path[current_index]

    if key == ':'
      key, current_index = capture_param(current_index:, path:)
    else
      current_index += 1
    end

    current_node = current_node.upsert_child(key:)
  end

  current_node.route = route
end

#root_path_nodeObject



20
21
22
# File 'lib/router/trie.rb', line 20

def root_path_node
  @root_node.nodes['/']
end