validate method

Validates and optionally normalizes a text value.

Implementation

ValidationResult<TextValidationIssue, String> validate(String input) {
  final value = config.trimWhitespace ? input.trim() : input;

  if (value.isEmpty) {
    if (config.allowEmpty) {
      return Right(value);
    }
    return const Left(TextEmptyIssue());
  }

  if (!config.allowOnlyWhitespace && value.trim().isEmpty) {
    return const Left(TextOnlyWhitespaceIssue());
  }

  if (config.minLength != null && value.length < config.minLength!) {
    return Left(
      TextTooShortIssue(
        currentLength: value.length,
        minLength: config.minLength!,
      ),
    );
  }

  if (config.maxLength != null && value.length > config.maxLength!) {
    return Left(
      TextTooLongIssue(
        currentLength: value.length,
        maxLength: config.maxLength!,
      ),
    );
  }

  if (config.pattern != null && !RegExp(config.pattern!).hasMatch(value)) {
    return Left(TextInvalidPatternIssue(config.pattern!));
  }

  if (config.allowedCharacters != null) {
    final invalidCharacters =
        value
            .split('')
            .where((char) => !config.allowedCharacters!.contains(char))
            .toSet()
            .join();
    if (invalidCharacters.isNotEmpty) {
      return Left(TextInvalidCharactersIssue(invalidCharacters));
    }
  }

  if (config.blacklistedWords.isNotEmpty) {
    final lowered = value.toLowerCase();
    final foundWords =
        config.blacklistedWords
            .where((word) => lowered.contains(word.toLowerCase()))
            .toList();
    if (foundWords.isNotEmpty) {
      return Left(TextContainsBlacklistedIssue(foundWords));
    }
  }

  return Right(value);
}