Pub Package

package:checked_yaml provides a checkedYamlDecode function that wraps the the creation of classes annotated for package:json_serializable it helps provide more helpful exceptions when the provided YAML is not compatible with the target type.

package:json_serializable can generate classes that can parse the YamlMap type provided by package:yaml when anyMap: true is specified for the class annotation.

@JsonSerializable(
  anyMap: true,
  checked: true,
  disallowUnrecognizedKeys: true,
)
class Configuration {
  @JsonKey(required: true)
  final String name;
  final int count;

  Configuration({required this.name, required this.count}) {
    if (name.isEmpty) {
      throw ArgumentError.value(name, 'name', 'Cannot be empty.');
    }
  }

  factory Configuration.fromJson(Map json) => _$ConfigurationFromJson(json);

  Map<String, dynamic> toJson() => _$ConfigurationToJson(this);

  @override
  String toString() => 'Configuration: ${toJson()}';
}

When checked: true is set, exceptions thrown when decoding an instance from a Map are wrapped in a CheckedFromJsonException. The checkedYamlDecode function catches these exceptions and throws a ParsedYamlException which maps the exception to the location in the input YAML with the error.

void main(List<String> arguments) {
  final sourcePathOrYaml = arguments.single;
  String yamlContent;
  Uri? sourceUri;

  if (FileSystemEntity.isFileSync(sourcePathOrYaml)) {
    yamlContent = File(sourcePathOrYaml).readAsStringSync();
    sourceUri = Uri.parse(sourcePathOrYaml);
  } else {
    yamlContent = sourcePathOrYaml;
  }

  final config = checkedYamlDecode(
    yamlContent,
    (m) => Configuration.fromJson(m!),
    sourceUrl: sourceUri,
  );
  print(config);
}

When parsing an invalid YAML file, an actionable error message is produced.

$ dart example/example.dart '{"name": "", "count": 1}'
Unhandled exception:
ParsedYamlException: line 1, column 10: Unsupported value for "name". Cannot be empty.
  ╷
1 │ {"name": "", "count": 1}
  │          ^^
  ╵

Libraries

checked_yaml