tokensToRegexp function

RegExp tokensToRegexp(
  1. List tokens,
  2. List<Key>? keys, {
  3. bool strict = false,
  4. bool start = true,
  5. bool end = true,
  6. String? delimiter,
  7. String? endsWith,
  8. String encode(
    1. String
    )?,
  9. bool sensitive = false,
})

Implementation

RegExp tokensToRegexp(
  List<Token> tokens,
  List<Key>? keys, {
  bool strict = false,
  bool start = true,
  bool end = true,
  String? delimiter,
  String? endsWith,
  String Function(String)? encode,
  bool sensitive = false,
}) {
  final encoder = encode ?? _defaultEncode;
  final _endsWith = '[${escapeString(endsWith ?? "")}]|\$';
  final _delimiter = '[${escapeString(delimiter ?? "/#?")}]';
  String route = start ? '^' : '';

  // Iterate over the tokens and create our regexp string.
  for (final token in tokens) {
    if (token is String) {
      route += escapeString(encoder(token));
    } else if (token is Key) {
      final prefix = escapeString(encoder(token.prefix));
      final suffix = escapeString(encoder(token.suffix));

      final groupName = ![null, ''].contains(token.name) && token.name is String
          ? '?<${token.name}>'
          : '';

      if (!['', null].contains(token.pattern)) {
        if (keys != null) {
          keys.add(token);
        }

        if (!['', null].contains(prefix) || !['', null].contains(suffix)) {
          if (token.modifier == '+' || token.modifier == '*') {
            final mod = token.modifier == '*' ? '?' : '';
            route +=
                '(?:$prefix((?:${token.pattern})(?:$suffix$prefix(?:${token.pattern}))*)$suffix)$mod';
          } else {
            route +=
                '(?:$prefix($groupName${token.pattern})$suffix)${token.modifier}';
          }
        } else {
          route += '($groupName${token.pattern})${token.modifier}';
        }
      } else {
        route += '(?:$prefix$suffix)${token.modifier}';
      }
    }
  }

  if (end) {
    if (!strict) {
      route += '$_delimiter?';
    }

    route += endsWith == null ? r'$' : '(?=$_endsWith)';
  } else {
    final endToken = tokens[tokens.length - 1];
    final isEndDelimited = endToken is String
        ? delimiter?.split('').contains(endToken[endToken.length - 1])
        : // tslint:disable-next-line
        endToken == null;

    if (!strict) {
      route += '(?:$_delimiter(?=$_endsWith))?';
    }

    if (isEndDelimited == null) {
      route += '(?=$_delimiter|$_endsWith)';
    }
  }

  return RegExp(route, caseSensitive: sensitive);
}