setPath static method

void setPath(
  1. Map<String, dynamic> root,
  2. String path,
  3. dynamic value
)

Sets value at a dotted/bracket path or JSON Pointer.

Examples:

  • body.status[0].Active
  • /body/status/0/Active

Implementation

static void setPath(Map<String, dynamic> root, String path, dynamic value) {
  final segments = parsePath(path);
  if (segments.isEmpty) {
    throw const FormatException('path is empty');
  }

  dynamic cursor = root;
  for (var i = 0; i < segments.length - 1; i++) {
    final segment = segments[i];
    final next = segments[i + 1];
    if (segment is String) {
      if (cursor is! Map) {
        throw FormatException('expected object before "$segment"');
      }
      final map = cursor;
      if (!map.containsKey(segment) || map[segment] == null) {
        map[segment] = next is int ? <dynamic>[] : <String, dynamic>{};
      }
      cursor = map[segment];
      if (next is int && cursor is! List) {
        throw FormatException('expected array at "$segment"');
      }
      if (next is String && cursor is! Map) {
        throw FormatException('expected object at "$segment"');
      }
    } else if (segment is int) {
      if (cursor is! List) {
        throw FormatException('expected array before index $segment');
      }
      while (cursor.length <= segment) {
        cursor.add(next is int ? <dynamic>[] : <String, dynamic>{});
      }
      cursor[segment] ??= next is int ? <dynamic>[] : <String, dynamic>{};
      cursor = cursor[segment];
      if (next is int && cursor is! List) {
        throw FormatException('expected array at index $segment');
      }
      if (next is String && cursor is! Map) {
        throw FormatException('expected object at index $segment');
      }
    }
  }

  final last = segments.last;
  if (last is String) {
    if (cursor is! Map) {
      throw FormatException('expected object before "$last"');
    }
    cursor[last] = value;
  } else if (last is int) {
    if (cursor is! List) {
      throw FormatException('expected array before index $last');
    }
    while (cursor.length <= last) {
      cursor.add(null);
    }
    cursor[last] = value;
  }
}