input method

Future<List<Result>> input({
  1. required String input,
  2. bool caseSensitive = false,
  3. bool? caseSensitiveFurtherSearches,
  4. int? minResults,
  5. int? maxResults,
})

Returns the possible completions of the given user input.

The researches are done in two times:

  • Basic researches that might return no result.
  • Forced further researches when the minimum of results is not reached

Minimum and maximum numbers of results.

The minimum number of results expected from this function can be specified with minResults. The maximum number of results expected from this function can be specified with maxResults.

When the minimum or results is reached, the "further researches" are not done. Otherwise, it forces to search more to try to get enough results as expected.

Never returns more than maxResults results.

Implementation

Future<List<Result>> input({
  required String input,
  bool caseSensitive = false,
  bool? caseSensitiveFurtherSearches,
  int? minResults,
  int? maxResults,
}) async {
  // No input, no results.
  if (input.isEmpty) {
    return [];
  }

  // Checks for strings starting with [input].
  final Future<List<Result>> startingResults = sherlock.queryBool(
    where: where,
    fn: (value) {
      // Only matches with strings.
      if (value.runtimeType != String) {
        return false;
      }

      if (!caseSensitive) {
        // Ignores the case
        return value.toLowerCase().startsWith(input.toLowerCase());
      }

      return value.startsWith(input);
    },
  );

  // Performs further searches to get at least minimum number of results
  // wanted.
  if (minResults != null && minResults > (await startingResults).length) {
    // Searches for keyword starting with the input.
    final Future<List<Result>> keywordStartingResults = sherlock.queryBool(
      where: where,
      fn: (value) {
        // Only matches with strings.
        if (value.runtimeType != String) {
          return false;
        }

        // If [caseSensitiveFurtherSearches] is not defined, [caseSensitive]
        // is used instead.
        if (!(caseSensitiveFurtherSearches ?? caseSensitive)) {
          // Ignores the case
          for (var keyword in value.toLowerCase().split(' ')) {
            if (keyword.startsWith(input.toLowerCase())) {
              return true;
            }
          }
        }

        for (var keyword in value.split(' ')) {
          if (keyword.startsWith(input.toLowerCase())) {
            return true;
          }
        }

        return false;
      },
    );

    // Searches the input in strings.
    final Future<List<Result>> inResults = sherlock.queryBool(
      where: where,
      fn: (value) {
        // Only matches with strings.
        if (value.runtimeType != String) {
          return false;
        }

        // If [caseSensitiveFurtherSearches] is not defined, [caseSensitive]
        // is used instead.
        if (!(caseSensitiveFurtherSearches ?? caseSensitive)) {
          // Ignores the case
          return value.toLowerCase().contains(input.toLowerCase());
        }

        return value.contains(input);
      },
    );

    // Collects results
    var results = await startingResults;
    _addListToList(results, await keywordStartingResults);
    _addListToList(results, await inResults);

    return _selectResults(
      results,
      minResults,
      maxResults,
    );
  }

  return _selectResults(
    await startingResults,
    minResults,
    maxResults,
  ).toSet().toList();
}