applyConstraints method

String applyConstraints(
  1. String schema,
  2. Element declaration,
  3. DartType type
)

Applies constraint annotations declared on a field or parameter.

Implementation

String applyConstraints(String schema, Element declaration, DartType type) {
  var output = schema;
  final isNumeric =
      type is InterfaceType &&
      (_core(type, 'int') || _core(type, 'double') || _core(type, 'num'));
  final isString = type is InterfaceType && _core(type, 'String');
  final isCollection =
      type is InterfaceType && (type.isDartCoreList || type.isDartCoreSet);
  final isSet = type is InterfaceType && type.isDartCoreSet;
  final setConstraints = <String>[];
  var hasUniqueConstraint = false;
  for (final metadata in declaration.metadata.annotations) {
    final value = metadata.computeConstantValue();
    final valueType = value?.type;
    if (value == null || valueType == null) continue;
    if (_min.isExactlyType(valueType)) {
      _require(declaration, type, '@Min', isNumeric, '@MinLength');
      output = '$output.min(${_number(value, 'value')})';
    } else if (_max.isExactlyType(valueType)) {
      _require(declaration, type, '@Max', isNumeric, '@MaxLength');
      output = '$output.max(${_number(value, 'value')})';
    } else if (_multipleOf.isExactlyType(valueType)) {
      _require(declaration, type, '@MultipleOf', isNumeric, 'numeric field');
      output = '$output.multipleOf(${_number(value, 'value')})';
    } else if (_positive.isExactlyType(valueType)) {
      _require(declaration, type, '@Positive', isNumeric, 'numeric field');
      output = '$output.positive()';
    } else if (_negative.isExactlyType(valueType)) {
      _require(declaration, type, '@Negative', isNumeric, 'numeric field');
      output = '$output.negative()';
    } else if (_minLength.isExactlyType(valueType)) {
      _require(declaration, type, '@MinLength', isString, '@Min');
      output = '$output.minLength(${value.getField('length')!.toIntValue()})';
    } else if (_maxLength.isExactlyType(valueType)) {
      _require(declaration, type, '@MaxLength', isString, '@Max');
      output = '$output.maxLength(${value.getField('length')!.toIntValue()})';
    } else if (_pattern.isExactlyType(valueType)) {
      _require(declaration, type, '@Pattern', isString, 'String field');
      output =
          '$output.matches(${dartStringLiteral(value.getField('pattern')!.toStringValue()!)})';
    } else if (_email.isExactlyType(valueType)) {
      _require(declaration, type, '@Email', isString, 'String field');
      output = '$output.email()';
    } else if (_url.isExactlyType(valueType)) {
      _require(declaration, type, '@Url', isString, 'String field');
      output = '$output.url()';
    } else if (_uri.isExactlyType(valueType)) {
      _require(declaration, type, '@Uri', isString, 'String field');
      output = '$output.uri()';
    } else if (_uuid.isExactlyType(valueType)) {
      _require(declaration, type, '@Uuid', isString, 'String field');
      output = '$output.uuid()';
    } else if (_date.isExactlyType(valueType)) {
      _require(declaration, type, '@Date', isString, 'String field');
      output = '$output.date()';
    } else if (_dateTime.isExactlyType(valueType)) {
      _require(declaration, type, '@DateTime', isString, 'String field');
      output = '$output.datetime()';
    } else if (_notEmpty.isExactlyType(valueType)) {
      _require(declaration, type, '@NotEmpty', isString, 'String field');
      output = '$output.notEmpty()';
    } else if (_minItems.isExactlyType(valueType)) {
      _require(
        declaration,
        type,
        '@MinItems',
        isCollection,
        'List or Set field',
      );
      final constraint =
          '.minItems(${value.getField('count')!.toIntValue()})';
      if (isSet) {
        setConstraints.add(constraint);
      } else {
        output = '$output$constraint';
      }
    } else if (_maxItems.isExactlyType(valueType)) {
      _require(
        declaration,
        type,
        '@MaxItems',
        isCollection,
        'List or Set field',
      );
      final constraint =
          '.maxItems(${value.getField('count')!.toIntValue()})';
      if (isSet) {
        setConstraints.add(constraint);
      } else {
        output = '$output$constraint';
      }
    } else if (_uniqueItems.isExactlyType(valueType)) {
      _require(
        declaration,
        type,
        '@UniqueItems',
        isCollection,
        'List or Set field',
      );
      if (isSet) {
        hasUniqueConstraint = true;
        setConstraints.add('.unique()');
      } else {
        output = '$output.unique()';
      }
    }
  }
  if (setConstraints.isNotEmpty) {
    if (isSet && !hasUniqueConstraint) {
      // A Set cannot retain duplicate values after decoding. Validate the
      // boundary with the same cardinality before the codec runs.
      setConstraints.add('.unique()');
    }
    final codec = output.lastIndexOf('.codec<');
    output = codec < 0
        ? '$output${setConstraints.join()}'
        : '${output.substring(0, codec)}${setConstraints.join()}'
              '${output.substring(codec)}';
  }
  return output;
}