Generic parsing

 avatar
unknown
dart
3 years ago
1.5 kB
6
Indexable
void main() {
  final mapInt = {
    'data': [1, 2, 3],
    'title': 'Int type',
  };
  print(Example.fromJson(mapInt));
  print(Example<int>.fromJson(mapInt));
  // print(Example<String>.fromJson(mapInt)); // Error!
  final mapStr = {
    'data': ['one', 'two', 'three'],
    'title': 'String type',
  };
  print(Example.fromJson(mapStr));
  print(Example<String>.fromJson(mapStr));
  final mapFoo = {
    'data': [
      {'x': 42, 's': 'foo'},
      {'x': 314, 's': 'pi*100'},
    ],
    'title': 'Foo type',
  };
  print(Example.fromJson(mapFoo)); // data items are not parsed to Foo
  // print(Example<Foo>.fromJson(mapFoo)); // Error!
  print(Example<Foo>.fromJsonTyped(mapFoo));
}

class Example<T> {
  Example(this.data, this.title);
  final List<T> data;
  final String title;

  factory Example.fromJson(Map<String, dynamic> json) =>
      Example<T>(List<T>.from(json['data']), json['title']);

  factory Example.fromJsonTyped(Map<String, dynamic> json) {
    if (T == Foo) {
      return Example<T>(List<T>.from(json['data'].map((j) => Foo.fromJson(j))),
          json['title']);
    } else {
      return Example<T>.fromJson(json);
    }
  }

  @override
  String toString() => '($T) $title - ${data.join(', ')}';
}

class Foo {
  final int x;
  final String s;

  Foo(this.x, this.s);

  factory Foo.fromJson(Map<String, dynamic> json) => Foo(json['x'], json['s']);

  @override
  String toString() {
    return super.toString() + ' Foo($x, $s)';
  }
}
Editor is loading...