mergeObj function

WithWarning<Map> mergeObj(
  1. Map obj,
  2. Map other,
  3. String path
)

Implementation

WithWarning<Map> mergeObj(Map obj, Map other, String path) {
  var warnings = <Warning>[];
  final clone = Map.from(obj);
  other.forEach((k, v) {
    if (clone[k] == null) {
      clone[k] = v;
    } else {
      final otherType = getTypeName(v);
      final t = getTypeName(clone[k]);
      if (t != otherType) {
        if (t == 'int' && otherType == 'double') {
          // if double was found instead of int, assign the double
          clone[k] = v;
        } else if (clone[k].runtimeType.toString() != 'double' &&
            v.runtimeType.toString() != 'int') {
          // if types are not equal, then
          warnings.add(newAmbiguousType('$path/$k'));
        }
      } else if (t == 'List') {
        var l = List.from(clone[k] as Iterable);
        l.addAll(other[k] as Iterable);
        final mergeableType = mergeableListType(l);
        if (ListType.Object == mergeableType.listType) {
          var mergedList = mergeObjectList(l, path);
          warnings.addAll(mergedList.warnings);
          clone[k] = List.filled(1, mergedList.result);
        } else {
          if (l.isNotEmpty) {
            clone[k] = List.filled(1, l[0]);
          }
          if (mergeableType.isAmbigous) {
            warnings.add(newAmbiguousType('$path/$k'));
          }
        }
      } else if (t == 'Class') {
        var mergedObj = mergeObj(clone[k] as Map, other[k] as Map, '$path/$k');
        warnings.addAll(mergedObj.warnings);
        clone[k] = mergedObj.result;
      }
    }
  });
  return WithWarning(clone, warnings);
}