lib/hanami/middleware/node.rb in hanami-router-2.0.2 vs lib/hanami/middleware/node.rb in hanami-router-2.1.0.beta1

- old
+ new

@@ -1,7 +1,9 @@ # frozen_string_literal: true +require "hanami/router/segment" + module Hanami module Middleware # Trie node to register scopes with custom Rack middleware # # @api private @@ -13,30 +15,50 @@ # @api private # @since 2.0.0 def initialize @app = nil - @children = {} + @variable = nil + @fixed = nil end # @api private # @since 2.0.0 def freeze - @children.freeze + @variable.freeze + @fixed.freeze super end # @api private # @since 2.0.0 def put(segment) - @children[segment] ||= self.class.new + if variable?(segment) + @variable ||= {} + @variable[segment_for(segment)] ||= self.class.new + else + @fixed ||= {} + @fixed[segment] ||= self.class.new + end end # @api private # @since 2.0.0 - def get(segment) - @children.fetch(segment) { self if leaf? } + def get(segment) # rubocop:disable Metrics/PerceivedComplexity + found = @fixed&.fetch(segment, nil) + return found if found + + @variable&.each do |matcher, node| + break if found + + captured = matcher.match(segment) + found = node if captured + end + + return found if found + + self if leaf? end # @api private # @since 2.0.0 def app!(app) @@ -50,10 +72,22 @@ end # @api private # @since 2.0.0 def leaf? - @children.empty? + @fixed.nil? && @variable.nil? + end + + # @api private + # @since 2.0.3 + def variable?(segment) + Router::ROUTE_VARIABLE_MATCHER.match?(segment) + end + + # @api private + # @since 2.0.3 + def segment_for(segment) + Router::Segment.fabricate(segment) end end end end