validate method

  1. @override
SchemaValidationResult validate(
  1. List<String> path,
  2. Object? value
)
override

Implementation

@override
SchemaValidationResult validate(List<String> path, Object? value) {
  if (value == null) {
    return optional
        ? SchemaValidationResult.valid(path)
        : SchemaValidationResult.requiredPropMissing(path);
  }

  final parsedValue = tryParse(value);

  if (parsedValue == null) {
    return SchemaValidationResult.invalidType(
      path,
      value,
      <String, dynamic>{}.toString(),
    );
  }

  final keys = parsedValue.keys.toSet();

  final required = properties.entries
      .where((entry) => !entry.value.optional)
      .map((entry) => entry.key);

  final requiredKeys = required.toSet();

  if (!keys.containsAll(requiredKeys)) {
    return SchemaValidationResult(
        key: path,
        errors: requiredKeys
            .difference(keys)
            .map(SchemaValidationError.requiredPropMissing)
            .toList());
  }

  if (additionalProperties == false) {
    final extraKeys = keys.difference(properties.keys.toSet());
    if (extraKeys.isNotEmpty) {
      return SchemaValidationResult(
        key: path,
        errors: extraKeys
            .map(SchemaValidationError.unallowedAdditionalProperty)
            .toList(),
      );
    }
  }

  for (final entry in parsedValue.entries) {
    final key = entry.key;
    final prop = properties[key];

    if (prop == null) {
      return additionalProperties == false
          ? SchemaValidationResult(key: path, errors: [
              SchemaValidationError.unallowedAdditionalProperty(key)
            ])
          : SchemaValidationResult.valid(path);
    }

    final result = prop.validate([...path, key], entry.value);
    if (!result.isValid) {
      return result;
    }
  }

  return SchemaValidationResult.valid(path);
}