match method

  1. @override
UriMatch? match(
  1. Uri uri
)
override

Returns a UriMatch describing the match if uri is matched by this pattern, otherwise returns null.

Implementation

@override
UriMatch? match(Uri uri) {
  final parameters = <String, String?>{};
  final restUriBuilder = UriBuilder();

  if (_pathRegex != null) {
    final match = _pathRegex!.matchAsPrefix(uri.path);
    if (match == null) {
      return null;
    } else {
      var i = 1;
      for (var param in _pathVariables) {
        parameters[param] = match.group(i++)!;
      }
      if (match.end < uri.path.length) {
        if (_pathSeparators.hasMatch(uri.path[match.end])) {
          restUriBuilder.path = uri.path.substring(match.end + 1);
        } else if (_pathSeparators.hasMatch(uri.path[match.end - 1])) {
          restUriBuilder.path = uri.path.substring(match.end);
        } else {
          return null;
        }
      }
    }
  } else {
    restUriBuilder.path = uri.path;
  }

  restUriBuilder.queryParameters.addAll(uri.queryParameters);

  if (_queryVariables.isNotEmpty) {
    // TODO(justinfagnani): remove matched parameters?
    for (var key in _queryVariables.keys) {
      final value = _queryVariables[key];
      if (value == null) {
        if (_queryParamsAreOptional || uri.queryParameters.containsKey(key)) {
          parameters[key] = uri.queryParameters[key];
        } else {
          return null;
        }
      } else if (uri.queryParameters[key] != value) {
        return null;
      }
    }
  }

  if (_fragmentRegex != null) {
    if (uri.fragment.isEmpty) return null;
    final match = _fragmentRegex!.matchAsPrefix(uri.fragment);
    final prefixMatch =
        _fragmentPrefixMatching && _pathSeparators.hasMatch(uri.fragment);
    if (match == null || (!prefixMatch && match.end != uri.fragment.length)) {
      return null;
    } else {
      var i = 1;
      for (var param in _fragmentVariables) {
        parameters[param] = match.group(i++)!;
      }
      if (prefixMatch) {
        if (match.end < uri.fragment.length) {
          if (_pathSeparators.hasMatch(uri.fragment[match.end])) {
            restUriBuilder.fragment = uri.fragment.substring(match.end + 1);
          } else if (_pathSeparators.hasMatch(uri.fragment[match.end - 1])) {
            restUriBuilder.fragment = uri.fragment.substring(match.end);
          } else {
            return null;
          }
        }
      }
    }
  }
  return UriMatch(this, uri, parameters, restUriBuilder.build());
}