Built-in Dart types topic

The package allows you to load a YAML string as a built-in Dart type without worrying about any wrapper classes that act as a bridge. Built-in types also supported by YAML include:

  • int, double, bool, null, String
  • List
  • Map

Tip

Each loader accepts a utility extension type called YamlSource. You can pass in the bytes for a yaml string or the actual string via the YamlSource.bytes and YamlSource.string constructors respectively.

Loading a scalar as a built-in Dart type

You can load a single Dart object from a YAML source string/bytes by calling loadDartObject which also accepts type params. The function returns a nullable type of the object your provide since the document may be empty.

// Type inferred automatically. A YAML spec philosophy!
print(
  loadDartObject<int>(
    source: YamlSource.string('24'),
  ),
);

print(
  loadDartObject<bool>(
    source: YamlSource.string('true'),
  ),
);

print(
  loadDartObject<double>(
    source: YamlSource.string('24.0'),
  ),
);

print(
  loadDartObject<String>(
    source: YamlSource.string('''
>+
24
'''),
  ),
);

Any directives, tags, anchors and aliases are stripped.

// true
print(loadDartObject<bool>(source: YamlSource.string('''
%YAML 1.2
%SOME directive
---
!!bool "true"
''')));

// Prints "Am I a ship?"
print(
  loadDartObject<String>(
    source: YamlSource.string('&anchor Am I a ship?'),
  ),
);

Loading a Sequence/Mapping as a built-in Dart List/Map

List and Map are returned as List<Object?> and Map<Object?, Object?>. This is intentional. Later versions may remove this restriction. You may need to explicitly cast it yourself to match the types you want. Providing List<T> or Map<K, V> will always throw.

The parser, however, guarantees that if a node only exists as type R in both Dart and YAML, calling cast<R> on the List<Object?> returned by the parser will not throw a runtime error. This also applies to a Map<K, V> returned as Map<Object?, Object?>.

This ensures the parser just works out of the box and doesn't trip itself from any unexpected type constraints.

// Dart throws. Casting happens after the list is already List<Object?> which Dart won't allow.
print(
  loadDartObject<List<int>>(
    source: YamlSource.string('[24, 25]'),
  ),
);

// Okay. [24, 25]
print(
  loadDartObject<List>(
    source: YamlSource.string('[24, 25]'),
  ),
);

// Enforce the cast later instead during iteration! Okay. [24, 25]
print(
  loadDartObject<List>(
    source: YamlSource.string('[24, 25]'),
  )?.cast<int>(),
);

// Okay. {key: value}
print(
  loadDartObject<Map>(
    source: YamlSource.string('{ key: value }'),
  ),
);

// Okay. {24: int, 25: cast}
print(
  loadDartObject<Map>(
    source: YamlSource.string('''
24: int
25: cast
'''),
  )?.cast<int, String>(),
);

Stripped anchors and aliases are evident in lists/maps. Each node is direct reference to the node it was aliased to (even maps and lists. Be careful!!)

// Prints: {value: [flow, value], flow: [flow, value]}
print(
  loadDartObject<Map>(
    source: YamlSource.string('''
&scalar value: &flow-list [ &flow flow, *scalar ]
*flow : *flow-list
'''),
  ),
);

Tip

You can configure the parser to dereference List and Map aliases, by default. The List or Map alias will be copied each time the parser needs it.

final list = loadDartObject<List>(
source: YamlSource.string('''
- &list [ flow, &map { key: value } ]
- *list
- *map
'''),
)!;

print(list[0] == list[1]); // Same list reference. True
print(list[0][1] == list[2]); // Same map reference. True
final list = loadDartObject<List>(
source: YamlSource.string('''
- &list [ flow, &map { key: value } ]
- *list
- *map
'''),
dereferenceAliases: true,
)!;

print(list[0] == list[1]); // Copies list. False.
print(list[0][1] == list[2]); // Copies map. False

Loading multiple documents

You can also load multiple documents by calling loadAsDartObjects. It explicitly returns a List<Object?> which contains the built-in Dart types for every root node in each document in the order the parser encountered/parsed them.

// Prints: [first, second, third]
print(
  loadDartObjects(
    source: YamlSource.string('''
# This document has no directives but uses doc end chars "..."

"first"
...

%THIS document
--- # Has a custom directive

"second"

--- # This document start here
    # No directives. Direct to node

"third"
'''),
  ),
);

Functions

loadAsDartObjects(YamlSource source, {bool dereferenceAliases = false, bool throwOnMapDuplicate = true, CustomTriggers? triggers, void logger(bool isInfo, String message)?}) List<Object?> Built-in Dart types
Loads every document's root node as a Dart object. This function guarantees that every object returned will be a primitive Dart type or a type inferred via the triggers provided.
loadDartObject<T>(YamlSource source, {bool dereferenceAliases = false, bool throwOnMapDuplicate = true, CustomTriggers? triggers, void logger(bool isInfo, String message)?}) → T? Built-in Dart types
Loads the first node as a Dart object. This function guarantees that every object returned will be a primitive Dart type or a type inferred via the triggers provided. A nullable T is returned in case the object could not be parsed.