generate method Null safety

String generate()

Generate the string using current properties

Implementation

String generate() {
  if ((minLength != null && maxLength != null && fixedLength != null) ||
      (minLength != null && fixedLength != null) ||
      (maxLength != null && fixedLength != null)) {
    throw RandomStringGeneratorException(
      'You should use either fixedLength or minLength and maxLength properties,'
      'not all of them at once.',
    );
  }

  bool usingFixed;

  if (minLength == null ||
      maxLength == null ||
      minLength! < 1 ||
      maxLength! <= minLength!) {
    if (fixedLength == null || fixedLength! < 1) {
      // didn't find either fixed or min and max
      throw RandomStringGeneratorException(
        'Random string length should be at least 1. '
        'If using min and max, then: min >= 1 and max > min',
      );
    } else {
      // using fixed
      usingFixed = true;
    }
  } else {
    // using min and max
    usingFixed = false;
  }

  var trueConditionsCounter = 0;

  if (hasAlpha) {
    if (alphaCase == AlphaCase.MIXED_CASE) {
      trueConditionsCounter += 2;
    } else {
      trueConditionsCounter += 1;
    }
  }
  if (hasDigits) {
    trueConditionsCounter += 1;
  }
  if (hasSymbols) {
    trueConditionsCounter += 1;
  }

  if (trueConditionsCounter < 1) {
    throw RandomStringGeneratorException(
      'You should set at least one "has" criteria '
      'to true in order to generate a random string ',
    );
  }

  var lengthToCheck = usingFixed ? fixedLength! : minLength!;
  if (lengthToCheck < trueConditionsCounter && mustHaveAtLeastOneOfEach) {
    throw RandomStringGeneratorException(
      'You set $trueConditionsCounter "has" params to true and '
      '"mustHaveAtLeastOneOfEach" also to true, '
      'but the (minimum) length ($lengthToCheck) is lower than $trueConditionsCounter, '
      'so this cannot generate at least one of each, '
      'because the total length is lower than that.',
    );
  }

  var _upperAlphabet =
      (customUpperAlphabet != null && customUpperAlphabet!.isNotEmpty)
          ? customUpperAlphabet
          : _upperAlphabetAsciiToString;

  var _lowerAlphabet =
      (customLowerAlphabet != null && customLowerAlphabet!.isNotEmpty)
          ? customLowerAlphabet
          : _lowerAlphabetAsciiToString;

  var _digits = (customDigits != null && customDigits!.isNotEmpty)
      ? customDigits
      : _digitsAsciiToString;

  var _symbols = (customSymbols != null && customSymbols!.isNotEmpty)
      ? customSymbols
      : _symbolsAsciiToString;

  var everyPossibleCharacterASCII = <String>[];
  var oneOfEach = <String>[];

  if (hasAlpha) {
    switch (alphaCase) {
      case AlphaCase.MIXED_CASE:
        everyPossibleCharacterASCII.addAll(_upperAlphabet!);
        everyPossibleCharacterASCII.addAll(_lowerAlphabet!);

        if (mustHaveAtLeastOneOfEach) {
          oneOfEach.add(
            _upperAlphabet[_secureRandom.nextInt(_upperAlphabet.length)],
          );
          oneOfEach.add(
            _lowerAlphabet[_secureRandom.nextInt(_lowerAlphabet.length)],
          );
        }
        break;
      case AlphaCase.UPPERCASE_ONLY:
        everyPossibleCharacterASCII.addAll(_upperAlphabet!);

        if (mustHaveAtLeastOneOfEach) {
          oneOfEach.add(
            _upperAlphabet[_secureRandom.nextInt(_upperAlphabet.length)],
          );
        }
        break;
      case AlphaCase.LOWERCASE_ONLY:
        everyPossibleCharacterASCII.addAll(_lowerAlphabet!);

        if (mustHaveAtLeastOneOfEach) {
          oneOfEach.add(
            _lowerAlphabet[_secureRandom.nextInt(_lowerAlphabet.length)],
          );
        }
        break;
      default:
        everyPossibleCharacterASCII.addAll(_upperAlphabet!);
        everyPossibleCharacterASCII.addAll(_lowerAlphabet!);

        if (mustHaveAtLeastOneOfEach) {
          oneOfEach.add(
            _upperAlphabet[_secureRandom.nextInt(_upperAlphabet.length)],
          );
          oneOfEach.add(
            _lowerAlphabet[_secureRandom.nextInt(_lowerAlphabet.length)],
          );
        }
    }
  }

  if (hasDigits) {
    everyPossibleCharacterASCII.addAll(_digits!);

    if (mustHaveAtLeastOneOfEach) {
      oneOfEach.add(_digits[_secureRandom.nextInt(_digits.length)]);
    }
  }

  if (hasSymbols) {
    everyPossibleCharacterASCII.addAll(_symbols!);

    if (mustHaveAtLeastOneOfEach) {
      oneOfEach.add(
        _symbols[_secureRandom.nextInt(_symbols.length)],
      );
    }
  }

  // start building the string
  var generatedString = <String>[];
  var expectedStringLength;

  if (usingFixed) {
    expectedStringLength = fixedLength;
  } else {
    var expectedMinLength = minLength!;
    var expectedMaxLength = maxLength!;

    expectedStringLength = expectedMinLength +
        _secureRandom.nextInt(
          expectedMaxLength - expectedMinLength + 1,
        );
  }

  if (mustHaveAtLeastOneOfEach) {
    generatedString.addAll(oneOfEach);
    expectedStringLength -= generatedString.length;
  }

  for (var i = 0; i < expectedStringLength!; i++) {
    var newChar = everyPossibleCharacterASCII[
        _secureRandom.nextInt(everyPossibleCharacterASCII.length)];
    generatedString.add(newChar);
  }

  return (generatedString..shuffle(_secureRandom)).join();
}