private function resolveWithMap()

in src/router/PrefixMatchingResolver.php [42:94]


  private function resolveWithMap(
    string $path,
    PrefixMap<TResponder> $map,
  ): (TResponder, dict<string, string>) {
    $literals = $map->getLiterals();
    if (C\contains_key($literals, $path)) {
      return tuple($literals[$path], dict[]);
    }

    $prefixes = $map->getPrefixes();
    if ($prefixes) {
      $prefix = Str\slice($path, 0, $map->getPrefixLength());
      if (C\contains_key($prefixes, $prefix)) {
        return $this->resolveWithMap(
          Str\slice($path, Str\length($prefix)),
          $prefixes[$prefix],
        );
      }
    }

    $regexps = $map->getRegexps();
    foreach ($regexps as $regexp => $_sub_map) {
      $pattern = '#^'.$regexp.'#';
      $matches = varray[];

      if (\preg_match_with_matches($pattern, $path, inout $matches) !== 1) {
        continue;
      }
      $matched = $matches[0];
      $remaining = Str\slice($path, Str\length($matched));

      $data = Dict\filter_keys($matches, $key ==> $key is string);
      $sub = $regexps[$regexp];

      if ($sub->isResponder()) {
        if ($remaining === '') {
          return tuple($sub->getResponder(), $data);
        }
        continue;
      }
      try {
        list($responder, $sub_data) = $this->resolveWithMap(
          $remaining,
          $sub->getMap(),
        );
      } catch (NotFoundException $_) {
        continue;
      }
      return tuple($responder, Dict\merge($data, $sub_data));
    }

    throw new NotFoundException();
  }