update method

void update(
  1. Iterable<Object?> path,
  2. Object? value
)

Sets value in the path.

There is a subtle difference between update and remove followed by an insertIntoList, because update preserves comments at the same level.

Throws a ArgumentError if path is invalid.

Throws an AliasException if a node on path is an alias or anchor.

Example: (using update)

final doc = YamlEditor('''
  - 0
  - 1 # comment
  - 2
''');
doc.update([1], 'test');

Expected Output:

  - 0
  - test # comment
  - 2

Example: (using remove and insertIntoList)

final doc2 = YamlEditor('''
  - 0
  - 1 # comment
  - 2
''');
doc2.remove([1]);
doc2.insertIntoList([], 1, 'test');

Expected Output:

  - 0
  - test
  - 2

Implementation

void update(Iterable<Object?> path, Object? value) {
  final valueNode = wrapAsYamlNode(value);

  if (path.isEmpty) {
    final start = _contents.span.start.offset;
    final end = getContentSensitiveEnd(_contents);
    final lineEnding = getLineEnding(_yaml);
    final edit = SourceEdit(
        start, end - start, yamlEncodeBlockString(valueNode, 0, lineEnding));

    return _performEdit(edit, path, valueNode);
  }

  final pathAsList = path.toList();
  final collectionPath = pathAsList.take(path.length - 1);
  final keyOrIndex = pathAsList.last;
  final parentNode = _traverse(collectionPath, checkAlias: true);

  if (parentNode is YamlList) {
    if (keyOrIndex is! int) {
      throw PathError(path, path, parentNode);
    }
    final expected = wrapAsYamlNode(
      [...parentNode.nodes]..[keyOrIndex] = valueNode,
    );

    return _performEdit(updateInList(this, parentNode, keyOrIndex, valueNode),
        collectionPath, expected);
  }

  if (parentNode is YamlMap) {
    final expectedMap =
        updatedYamlMap(parentNode, (nodes) => nodes[keyOrIndex] = valueNode);
    return _performEdit(updateInMap(this, parentNode, keyOrIndex, valueNode),
        collectionPath, expectedMap);
  }

  throw PathError.unexpected(
      path, 'Scalar $parentNode does not have key $keyOrIndex');
}