methods method

  1. @override
Map<String, Function> methods()
override

Implementation

@override
Map<String, Function> methods() {
  return {
    'stringify': (dynamic value, [dynamic replacer, dynamic space]) {
      dynamic replacerFn;
      if (replacer is Function) {
        replacerFn = replacer;
      }

      int? indent;
      if (space is num) indent = space.toInt();
      if (space is String) indent = space.length;

      dynamic applyReplacer(String key, dynamic val) {
        if (replacerFn != null) {
          return replacerFn([key, val]);
        }
        return val;
      }

      final activeObjects = Set<Object>.identity();

      dynamic walk(dynamic key, dynamic val) {
        val = applyReplacer(key.toString(), val);
        if (InvokableController.isArrayHole(val)) {
          return null;
        }
        if (val is Map) {
          if (!activeObjects.add(val)) {
            throw JSException(1, 'Converting circular structure to JSON');
          }
          try {
            Map<String, dynamic> m = {};
            for (final k in InvokableController.ownEnumerableKeys(val)) {
              m[k.toString()] =
                  walk(k.toString(), InvokableController.getProperty(val, k));
            }
            return m;
          } finally {
            activeObjects.remove(val);
          }
        } else if (val is List) {
          if (!activeObjects.add(val)) {
            throw JSException(1, 'Converting circular structure to JSON');
          }
          try {
            return val
                .asMap()
                .entries
                .map((e) => walk(e.key.toString(), e.value))
                .toList();
          } finally {
            activeObjects.remove(val);
          }
        }
        return val;
      }

      final processed = walk('', value);
      if (indent != null && indent > 0) {
        return const JsonEncoder.withIndent('  ').convert(processed);
      }
      return jsonEncode(processed);
    },
    'parse': (String value, [dynamic reviver]) {
      dynamic parsed = json.decode(value);
      if (reviver is! Function) return parsed;

      dynamic walk(dynamic key, dynamic val) {
        if (val is Map) {
          final Map<String, dynamic> m = {};
          val.forEach((k, v) {
            m[k] = walk(k, v);
          });
          return reviver([key, m]);
        } else if (val is List) {
          final list = val
              .asMap()
              .entries
              .map((e) => walk(e.key.toString(), e.value))
              .toList();
          return reviver([key, list]);
        } else {
          return reviver([key, val]);
        }
      }

      return walk('', parsed);
    }
  };
}