UriPattern.parse constructor

UriPattern.parse(
  1. String uri
)

Implementation

factory UriPattern.parse(String uri) {
  if (uri.endsWith('?')) {
    throw InvalidUriPatternError(
      'URI patterns must not end with "?". Found $uri',
    );
  } else if (!uri.startsWith('/')) {
    throw InvalidUriPatternError(
      'URI pattern must start with "/". Found $uri',
    );
  } else if (uri.contains('#')) {
    throw InvalidUriPatternError(
      'URI pattern must not contain a fragment. Found $uri',
    );
  }

  final parts = uri.split('?');
  final unparsedSegments = parts[0].split('/');
  final segments = <Segment>[];

  // Skip the first '/' segment, and thus assume offset of 1.
  for (var i = 1; i < unparsedSegments.length; i++) {
    final segment = unparsedSegments[i];
    if (i == unparsedSegments.length - 1 && segment.isEmpty) {
      break;
    }
    segments.add(Segment.parse(segment));
  }

  final queryLiterals = <String, String>{};
  // Parse the query literals outside of the general pattern
  if (parts.length == 2) {
    if (parts[1].contains('{') || parts[1].contains('}')) {
      throw InvalidUriPatternError(
        'URI labels must not appear in the query string. Found $uri',
      );
    }
    for (final kvp in parts[1].split('&')) {
      final parameterParts = kvp.split('=');
      final actualKey = parameterParts[0];
      if (queryLiterals.containsKey(actualKey)) {
        throw InvalidUriPatternError(
          'Literal query parameters must not be repeated: $uri',
        );
      }
      queryLiterals[actualKey] =
          parameterParts.length == 2 ? parameterParts[1] : '';
    }
  }

  return UriPattern(
    pattern: uri,
    segments: segments,
    queryLiterals: queryLiterals,
  );
}