Created
December 14, 2020 18:11
-
-
Save sma/e77d28237678de05b0a8406c88ae092d to your computer and use it in GitHub Desktop.
a typesafe wrapper for accessing json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Json extends Iterable<Json> { | |
Json(this.value); | |
Json.from(String s) : this(jsonDecode(s)); | |
final dynamic value; | |
@override | |
String toString() => jsonEncode(value); | |
bool get isNull => value == null; | |
bool get isBool => value is bool; | |
bool get isNum => value is num; | |
bool get isInt => value is int; | |
bool get isDouble => value is double; | |
bool get isString => value is String; | |
bool get isArray => value is List; | |
bool get isObject => value is Map; | |
bool get asBool => value as bool; | |
num get asNum => value as num; | |
int get asInt => asNum.toInt(); | |
double get asDouble => asNum.toDouble(); | |
String get asString => value as String; | |
List<Json> get asArray => (value as List).map((e) => Json(e)).toList(); | |
Map<String, Json> get asObject => (value as Map).map((k, v) => MapEntry(k, Json(v))); | |
bool? get optBool => value as bool?; | |
num? get optNum => value as num?; | |
int? get optInt => optNum?.toInt(); | |
double? get optDouble => optNum?.toDouble(); | |
String? get optString => value as String?; | |
List<Json>? get optArray => (value as List?)?.map((e) => Json(e)).toList(); | |
Map<String, Json>? get optObject => (value as Map?)?.map((k, v) => MapEntry(k, Json(v))); | |
/// Returns the JSON value at [key] which must be either an `int` or a `String`, depending | |
/// on whether the receiver is an array or an object. If the receiver is `null`, `null` is | |
/// returned and the [key] is ignored. If the [key] doesn't exist, `Json(null)` is returned. | |
Json operator [](dynamic key) { | |
if (value == null) return this; | |
if (value is List) { | |
final index = (key as num).toInt(); | |
return Json(index >= 0 && index < value.length ? value[index] : null); | |
} | |
if (value is Map<String, dynamic>) return Json(value[key.toString()]); | |
throw TypeError(); | |
} | |
@override | |
Iterator<Json> get iterator => asArray.iterator; | |
/// Creates a instance of [T] by applying [decode] to the receiver. | |
/// If the receiver is `null`, `null` is returned. | |
/// The [decode] function should throw a [TypeError] is something doesn't match. | |
T? of<T>(T Function(Json) decode) => isNull ? null : decode(value); | |
/// Creates a list of instances of [T] by applying [decode] to all array elements if the receiver is an array. | |
/// If the receiver is `null`, `null` is returned. | |
/// If the receiver isn't an array and isn't `null`, a [TypeError] is thrown. | |
/// The [decode] function should throw a [TypeError] is something doesn't match. | |
List<T>? mapOf<T>(T Function(Json) decode) => (value as List?)?.map((e) => decode(Json(e))).toList(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment