match method

  1. @override
List<FutureOr<List<RepeatMatch>>> match(
  1. String password
)
override

Should return the matches for the password.

A synchronous matcher should return a list (usually of length 1) of lists of matches. An asynchronous matcher can return a list of futures that completes with a list of matches.

Implementation

@override
List<FutureOr<List<RepeatMatch>>> match(String password) {
  final List<RepeatMatch> matches = <RepeatMatch>[];
  final List<Future<RepeatMatch>> futures = <Future<RepeatMatch>>[];
  int lastIndex = 0;
  while (lastIndex < password.length) {
    final RegExpMatch? greedyMatch =
        _greedyRegExp.firstMatch(password.substring(lastIndex));
    final RegExpMatch? lazyMatch =
        _lazyRegExp.firstMatch(password.substring(lastIndex));
    if (greedyMatch == null || lazyMatch == null) break;
    RegExpMatch match;
    String baseToken = '';
    if (greedyMatch[0]!.length > lazyMatch[0]!.length) {
      // Greedy beats lazy for 'aabaab':
      // greedy: [aabaab, aab]
      // lazy: [aa, a].
      match = greedyMatch;
      // Greedy repeated string might itself be repeated, eg.
      // aabaab in aabaabaabaab.
      // Run an anchored lazy match on greedy repeated string
      // to find the shortest repeated string.
      final RegExpMatch? temp = _lazyAnchoredRegExp.firstMatch(match[0]!);
      if (temp != null) {
        baseToken = temp[1]!;
      }
    } else {
      // Lazy beats greedy for 'aaaaa':
      // greedy: [aaaa, aa]
      // lazy: [aaaaa, a].
      match = lazyMatch;
      baseToken = match[1]!;
    }
    final int start = lastIndex + match.start;
    final int end = lastIndex + match.end;
    final FutureOr<RepeatMatch> repeatMatch =
        // ignore: discarded_futures
        _repeatMatch(password, start, end, baseToken);
    if (repeatMatch is RepeatMatch) {
      matches.add(repeatMatch);
    } else {
      futures.add(repeatMatch);
    }
    lastIndex = end;
  }
  return <FutureOr<List<RepeatMatch>>>[
    matches,
    // ignore: discarded_futures
    if (futures.isNotEmpty) Future.wait(futures),
  ];
}