@@ -17,7 +17,7 @@ final class RouteTreeNode
1717 /** @var array<string, RouteTreeNode> */
1818 private array $ dynamicPaths = [];
1919
20- private ?MarkedRoute $ leaf = null ;
20+ private ?MarkedRoute $ targetRoute = null ;
2121
2222 private function __construct (
2323 public readonly RouteTreeNodeType $ type ,
@@ -40,34 +40,26 @@ public static function createStaticRouteNode(string $name): self
4040 return new self (RouteTreeNodeType::Static, $ name );
4141 }
4242
43- public function addPath ( array $ pathSegments , MarkedRoute $ markedRoute ): void
43+ public function findOrCreateNodeForSegment ( string $ routeSegment ): self
4444 {
45- // If path segments is empty this node should target to given marked route
46- if ($ pathSegments === []) {
47- if ($ this ->leaf !== null ) {
48- throw new DuplicateRouteException ($ markedRoute ->route );
49- }
50-
51- $ this ->leaf = $ markedRoute ;
45+ // Translates a path segment like {id} into it's matching regex. Static segments remain the same
46+ $ regexRouteSegment = self ::convertDynamicSegmentToRegex ($ routeSegment );
5247
53- return ;
48+ // Returns a static or dynamic child node depending on the segment is dynamic or static
49+ if ($ routeSegment === $ regexRouteSegment ) {
50+ return $ this ->staticPaths [$ regexRouteSegment ] ??= self ::createStaticRouteNode ($ routeSegment );
5451 }
5552
56- // Removes the first element of the pathSegments and use it to determin the next routing node
57- $ currentPathSegment = array_shift ($ pathSegments );
58-
59- // Translates a path segment like {id} into it's matching regex. Static segments remain the same
60- $ regexPathSegment = self ::convertDynamicSegmentToRegex ($ currentPathSegment );
53+ return $ this ->dynamicPaths [$ regexRouteSegment ] ??= self ::createDynamicRouteNode ($ regexRouteSegment );
54+ }
6155
62- // Find or create the next node to recurse into
63- if ($ currentPathSegment !== $ regexPathSegment ) {
64- $ node = $ this ->dynamicPaths [$ regexPathSegment ] ??= self ::createDynamicRouteNode ($ regexPathSegment );
65- } else {
66- $ node = $ this ->staticPaths [$ regexPathSegment ] ??= self ::createStaticRouteNode ($ currentPathSegment );
56+ public function setTargetRoute (MarkedRoute $ markedRoute ): void
57+ {
58+ if ($ this ->targetRoute !== null ) {
59+ throw new DuplicateRouteException ($ markedRoute ->route );
6760 }
6861
69- // Recurse into the newly created node to add the remainder of the path segments
70- $ node ->addPath ($ pathSegments , $ markedRoute );
62+ $ this ->targetRoute = $ markedRoute ;
7163 }
7264
7365 private static function convertDynamicSegmentToRegex (string $ uriPart ): string
@@ -107,14 +99,14 @@ public function toRegex(): string
10799 // Add a leaf alteration with an optional slash and end of line match `$`.
108100 // The `(*MARK:x)` is a marker which when this regex is matched will cause the matches array to contain
109101 // a key `"MARK"` with value `"x"`, it is used to track which route has been matched
110- if ($ this ->leaf !== null ) {
111- $ regexp .= '|\/?$(* ' . MarkedRoute::REGEX_MARK_TOKEN . ': ' . $ this ->leaf ->mark . ') ' ;
102+ if ($ this ->targetRoute !== null ) {
103+ $ regexp .= '|\/?$(* ' . MarkedRoute::REGEX_MARK_TOKEN . ': ' . $ this ->targetRoute ->mark . ') ' ;
112104 }
113105
114106 $ regexp .= ") " ;
115- } elseif ($ this ->leaf !== null ) {
107+ } elseif ($ this ->targetRoute !== null ) {
116108 // Add a singular leaf regex without alteration
117- $ regexp .= '\/?$(* ' . MarkedRoute::REGEX_MARK_TOKEN . ': ' . $ this ->leaf ->mark . ') ' ;
109+ $ regexp .= '\/?$(* ' . MarkedRoute::REGEX_MARK_TOKEN . ': ' . $ this ->targetRoute ->mark . ') ' ;
118110 }
119111
120112 return $ regexp ;
0 commit comments