getPathMatch method

VPathMatch getPathMatch({
  1. required String entirePath,
  2. required String? selfPath,
  3. required RegExp? selfPathRegExp,
  4. required List<String> selfPathParametersKeys,
  5. required VPathMatch parentVPathMatch,
})

Returns path information given a local path.

entirePath is the whole path, useful when selfPathRegExp is absolute remainingPathFromParent is the path that remain after removing the parent paths, useful when selfPathRegExp relative selfPathRegExp the RegExp corresponding to the path that should be tested

Returns a VPathMatch which holds two information:

  • The remaining path, after having removed the selfPathRegExp (null if there is no match)
  • The path parameters gotten from selfPathRegExp and the path, added to the parentPathParameters if relative path

Implementation

VPathMatch getPathMatch(
    {required String entirePath,
    required String? selfPath,
    required RegExp? selfPathRegExp,
    required List<String> selfPathParametersKeys,
    required VPathMatch parentVPathMatch}) {
  if (selfPath == null) {
    return parentVPathMatch;
  }

  // if selfPath is not null, neither should selfPathRegExp be
  assert(selfPathRegExp != null);

  // If our path starts with '/', this is an absolute path
  if ((selfPath.startsWith('/'))) {
    final match = selfPathRegExp!.matchAsPrefix(entirePath);

    if (match == null) {
      return InvalidVPathMatch(
        localPath: getConstantLocalPath(),
        names: parentVPathMatch.names,
      );
    }

    var remainingPath = entirePath.substring(match.end);
    final localPath = entirePath.substring(match.start, match.end);
    final pathParameters = extract(selfPathParametersKeys, match)
      ..updateAll((key, value) => Uri.decodeComponent(value));

    // Remove the trailing '/' in remainingPath if needed
    if (remainingPath.startsWith('/'))
      remainingPath = remainingPath.replaceFirst('/', '');

    return ValidVPathMatch(
      remainingPath: remainingPath,
      pathParameters: pathParameters,
      localPath: localPath,
      names: parentVPathMatch.names,
    );
  }

  // Else our path is relative
  final String? thisConstantLocalPath = getConstantLocalPath();
  final String? constantLocalPath =
      (parentVPathMatch.localPath == null && thisConstantLocalPath == null)
          ? null
          : (parentVPathMatch.localPath == null)
              ? thisConstantLocalPath
              : (thisConstantLocalPath == null)
                  ? parentVPathMatch.localPath
                  : parentVPathMatch.localPath! +
                      (parentVPathMatch.localPath!.endsWith('/') ? '' : '/') +
                      thisConstantLocalPath;

  if (parentVPathMatch is ValidVPathMatch) {
    // We try to remove this part of the path from the remainingPathFromParent
    final match =
        selfPathRegExp!.matchAsPrefix(parentVPathMatch.remainingPath);

    if (match == null) {
      return InvalidVPathMatch(
        localPath: constantLocalPath,
        names: parentVPathMatch.names,
      );
    }

    var remainingPath = parentVPathMatch.remainingPath.substring(match.end);
    final localPath =
        parentVPathMatch.remainingPath.substring(match.start, match.end);
    final pathParameters = {
      ...parentVPathMatch.pathParameters,
      ...extract(selfPathParametersKeys, match)
        ..updateAll((key, value) => Uri.decodeComponent(value)),
    };

    // Remove the trailing '/' in remainingPath if needed
    if (remainingPath.startsWith('/'))
      remainingPath = remainingPath.replaceFirst('/', '');

    return ValidVPathMatch(
      remainingPath: remainingPath,
      pathParameters: pathParameters,
      localPath: localPath,
      names: parentVPathMatch.names,
    );
  }

  return InvalidVPathMatch(
    localPath: constantLocalPath,
    names: parentVPathMatch.names,
  );
}