Skip to content

Instantly share code, notes, and snippets.

@eernstg
Last active July 28, 2023 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eernstg/9c68ed5a11867e6e2085816f14a483bf to your computer and use it in GitHub Desktop.
Save eernstg/9c68ed5a11867e6e2085816f14a483bf to your computer and use it in GitHub Desktop.
A variant of the 'Dart decoding using dart:convert' example using extension types
import 'package:http/http.dart' as http;
import 'dart:convert';
main() async {
const pubUrl = "https://pub.dartlang.org/api/packages/protobuf";
var response = await http.get(Uri.parse(Uri.encodeFull(pubUrl)));
if (response.statusCode == 200) {
PkgInfo info = PkgInfo(json.decode(response.body));
print('Package ${info.name}, v ${info.latest.pubspec.version}');
} else {
throw Exception('Failed to load package info');
}
}
extension type PkgInfo(Map<String, dynamic> json) {
String get name => json['name']!;
PkgVersion get latest => PkgVersion(json['latest']!);
String get version => json['version']!;
}
extension type PkgVersion(Map<String, dynamic> json) {
String get archiveUrl => json['archive_url']!;
PkgPubspec get pubspec => PkgPubspec(json['pubspec']!);
}
extension type PkgPubspec(Map<String, dynamic> json) {
String get version => json['version']!;
String get name => json['name']!;
}
@eernstg
Copy link
Author

eernstg commented Jul 26, 2023

It might be cool to have nested extension members (similar to Kotlin's):

typedef JsonMap = Map<String, dynamic>;

extension type _Base(JsonMap json) {
  (String s).operator ~() => json[s]!;
}

extension type PkgInfo(JsonMap json) implements _Base {
  String get name => ~'name';
  PkgVersion get latest => PkgVersion(~'latest');
  String get version => ~'version';
}

extension type PkgVersion(JsonMap json) implements _Base {
  String get archiveUrl => ~'archive_url';
  PkgPubspec get pubspec => PkgPubspec(~'pubspec');
}

extension type PkgPubspec(JsonMap json) implements _Base {
  String get version => ~'version';
  String get name => ~'name';
}

They're a bit weird, though, because they can only be invoked in a context where the current instance of the enclosing type declaration is available implicitly (for instance, inside the body of the declaration of _Base), such that there is a way to give meaning to expressions like json.

But I digress. ;-)

@eernstg
Copy link
Author

eernstg commented Jul 27, 2023

dart-lang/language#3240 explores this idea further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment