matchRoute method

AppRouteMatch? matchRoute(
  1. String path
)

Implementation

AppRouteMatch? matchRoute(String path) {
  var usePath = path;

  if (usePath.startsWith("/")) {
    usePath = path.substring(1);
  }

  var components = usePath.split("/");

  if (path == Navigator.defaultRouteName) {
    components = ["/"];
  }

  var nodeMatches = <RouteTreeNode, RouteTreeNodeMatch>{};
  var nodesToCheck = _nodes;

  for (final checkComponent in components) {
    final currentMatches = <RouteTreeNode, RouteTreeNodeMatch>{};
    final nextNodes = <RouteTreeNode>[];

    var pathPart = checkComponent;
    Map<String, List<String>>? queryMap;

    if (checkComponent.contains("?")) {
      var splitParam = checkComponent.split("?");
      pathPart = splitParam[0];
      queryMap = parseQueryString(splitParam[1]);
    }

    for (final node in nodesToCheck) {
      final isMatch = (node.part == pathPart || node.isParameter());

      if (isMatch) {
        RouteTreeNodeMatch? parentMatch = nodeMatches[node.parent];
        final match = RouteTreeNodeMatch.fromMatch(parentMatch, node);
        if (node.isParameter()) {
          final paramKey = node.part.substring(1);
          match.parameters[paramKey] = [pathPart];
        }
        if (queryMap != null) {
          match.parameters.addAll(queryMap);
        }
        currentMatches[node] = match;
        nextNodes.addAll(node.nodes);
      }
    }

    nodeMatches = currentMatches;
    nodesToCheck = nextNodes;

    if (currentMatches.values.length == 0) {
      return null;
    }
  }

  final matches = nodeMatches.values.toList();

  if (matches.isNotEmpty) {
    final match = matches.first;
    final nodeToUse = match.node;
    final routes = nodeToUse.routes;

    if (routes.isNotEmpty) {
      final routeMatch = AppRouteMatch(routes[0]);
      routeMatch.parameters = match.parameters;
      return routeMatch;
    }
  }

  return null;
}