diff --git a/analysis_options.yaml b/analysis_options.yaml index 09e9d99d..58ead17c 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -11,7 +11,7 @@ linter: analyzer: language: - strict-casts: false + strict-casts: true strict-inference: true strict-raw-types: true errors: diff --git a/lib/fake_matrix_api.dart b/lib/fake_matrix_api.dart index 3d7f420b..3a63be40 100644 --- a/lib/fake_matrix_api.dart +++ b/lib/fake_matrix_api.dart @@ -31,12 +31,12 @@ import 'package:matrix_api_lite/matrix_api_lite.dart'; Map decodeJson(dynamic data) { if (data is String) { - return json.decode(data); + return json.decode(data) as Map; } if (data is Map && data.isEmpty) { return {}; } - return data; + return data as Map; } T? tryCast(dynamic object) => object is T ? object : null; diff --git a/lib/src/matrix_api.dart b/lib/src/matrix_api.dart index e768c4d5..772fc58d 100644 --- a/lib/src/matrix_api.dart +++ b/lib/src/matrix_api.dart @@ -47,7 +47,10 @@ class MatrixApi extends Api { @override Never unexpectedResponse(http.BaseResponse response, Uint8List body) { if (response.statusCode >= 400 && response.statusCode < 500) { - throw MatrixException.fromJson(json.decode(utf8.decode(body))); + final resp = json.decode(utf8.decode(body)); + if (resp is Map) { + throw MatrixException.fromJson(resp); + } } super.unexpectedResponse(response, body); } @@ -164,7 +167,7 @@ class MatrixApi extends Api { }, }, ); - return Map.from(response['one_time_key_counts']); + return Map.from(response['one_time_key_counts'] as Map); } /// This endpoint allows the creation, modification and deletion of pushers diff --git a/lib/src/model/auth/authentication_data.dart b/lib/src/model/auth/authentication_data.dart index 02633ca3..a01faafc 100644 --- a/lib/src/model/auth/authentication_data.dart +++ b/lib/src/model/auth/authentication_data.dart @@ -30,8 +30,8 @@ class AuthenticationData { AuthenticationData({this.type, this.session}); AuthenticationData.fromJson(Map json) - : type = json['type'], - session = json['session']; + : type = json['type'] as String?, + session = json['session'] as String?; Map toJson() { final data = {}; diff --git a/lib/src/model/auth/authentication_identifier.dart b/lib/src/model/auth/authentication_identifier.dart index ada4778a..e02cf840 100644 --- a/lib/src/model/auth/authentication_identifier.dart +++ b/lib/src/model/auth/authentication_identifier.dart @@ -32,7 +32,7 @@ class AuthenticationIdentifier { AuthenticationIdentifier({required this.type}); AuthenticationIdentifier.fromJson(Map json) - : type = json['type']; + : type = json['type'] as String; factory AuthenticationIdentifier.subFromJson(Map json) { switch (json['type']) { diff --git a/lib/src/model/auth/authentication_password.dart b/lib/src/model/auth/authentication_password.dart index b47a17be..4135a535 100644 --- a/lib/src/model/auth/authentication_password.dart +++ b/lib/src/model/auth/authentication_password.dart @@ -41,8 +41,9 @@ class AuthenticationPassword extends AuthenticationData { ); AuthenticationPassword.fromJson(Map json) - : password = json['password'], - identifier = AuthenticationIdentifier.subFromJson(json['identifier']), + : password = json['password'] as String, + identifier = AuthenticationIdentifier.subFromJson( + json['identifier'] as Map), super.fromJson(json); @override diff --git a/lib/src/model/auth/authentication_phone_identifier.dart b/lib/src/model/auth/authentication_phone_identifier.dart index e6eb8aa6..0c79d7d3 100644 --- a/lib/src/model/auth/authentication_phone_identifier.dart +++ b/lib/src/model/auth/authentication_phone_identifier.dart @@ -32,8 +32,8 @@ class AuthenticationPhoneIdentifier extends AuthenticationIdentifier { : super(type: AuthenticationIdentifierTypes.phone); AuthenticationPhoneIdentifier.fromJson(Map json) - : country = json['country'], - phone = json['phone'], + : country = json['country'] as String, + phone = json['phone'] as String, super.fromJson(json); @override diff --git a/lib/src/model/auth/authentication_recaptcha.dart b/lib/src/model/auth/authentication_recaptcha.dart index 20c8d3c2..5244e16d 100644 --- a/lib/src/model/auth/authentication_recaptcha.dart +++ b/lib/src/model/auth/authentication_recaptcha.dart @@ -34,7 +34,7 @@ class AuthenticationRecaptcha extends AuthenticationData { ); AuthenticationRecaptcha.fromJson(Map json) - : response = json['response'], + : response = json['response'] as String, super.fromJson(json); @override diff --git a/lib/src/model/auth/authentication_third_party_identifier.dart b/lib/src/model/auth/authentication_third_party_identifier.dart index 2860dfdf..f40fd98b 100644 --- a/lib/src/model/auth/authentication_third_party_identifier.dart +++ b/lib/src/model/auth/authentication_third_party_identifier.dart @@ -33,8 +33,8 @@ class AuthenticationThirdPartyIdentifier extends AuthenticationIdentifier { : super(type: AuthenticationIdentifierTypes.thirdParty); AuthenticationThirdPartyIdentifier.fromJson(Map json) - : medium = json['medium'], - address = json['address'], + : medium = json['medium'] as String, + address = json['address'] as String, super.fromJson(json); @override diff --git a/lib/src/model/auth/authentication_three_pid_creds.dart b/lib/src/model/auth/authentication_three_pid_creds.dart index b6278160..a1a119de 100644 --- a/lib/src/model/auth/authentication_three_pid_creds.dart +++ b/lib/src/model/auth/authentication_three_pid_creds.dart @@ -66,10 +66,10 @@ class ThreepidCreds { this.idAccessToken}); ThreepidCreds.fromJson(Map json) - : sid = json['sid'], - clientSecret = json['client_secret'], - idServer = json['id_server'], - idAccessToken = json['id_access_token']; + : sid = json['sid'] as String, + clientSecret = json['client_secret'] as String, + idServer = json['id_server'] as String?, + idAccessToken = json['id_access_token'] as String?; Map toJson() { final data = {}; diff --git a/lib/src/model/auth/authentication_token.dart b/lib/src/model/auth/authentication_token.dart index fd9c18cd..7c86bd45 100644 --- a/lib/src/model/auth/authentication_token.dart +++ b/lib/src/model/auth/authentication_token.dart @@ -37,8 +37,8 @@ class AuthenticationToken extends AuthenticationData { ); AuthenticationToken.fromJson(Map json) - : token = json['token'], - txnId = json['txn_id'], + : token = json['token'] as String, + txnId = json['txn_id'] as String?, super.fromJson(json); @override diff --git a/lib/src/model/auth/authentication_user_identifier.dart b/lib/src/model/auth/authentication_user_identifier.dart index 9070dc48..1736c47a 100644 --- a/lib/src/model/auth/authentication_user_identifier.dart +++ b/lib/src/model/auth/authentication_user_identifier.dart @@ -31,7 +31,7 @@ class AuthenticationUserIdentifier extends AuthenticationIdentifier { : super(type: AuthenticationIdentifierTypes.userId); AuthenticationUserIdentifier.fromJson(Map json) - : user = json['user'], + : user = json['user'] as String, super.fromJson(json); @override diff --git a/lib/src/model/basic_event.dart b/lib/src/model/basic_event.dart index 5ea833f1..e91c2e80 100644 --- a/lib/src/model/basic_event.dart +++ b/lib/src/model/basic_event.dart @@ -33,7 +33,7 @@ class BasicEvent { }); BasicEvent.fromJson(Map json) - : type = json['type'], + : type = json['type'] as String, content = (json['content'] as Map).copy(); Map toJson() { diff --git a/lib/src/model/basic_event_with_sender.dart b/lib/src/model/basic_event_with_sender.dart index 6618fc5a..cb3a6486 100644 --- a/lib/src/model/basic_event_with_sender.dart +++ b/lib/src/model/basic_event_with_sender.dart @@ -33,7 +33,7 @@ class BasicEventWithSender extends BasicEvent { : super(type: type, content: content); BasicEventWithSender.fromJson(Map json) - : senderId = json['sender'], + : senderId = json['sender'] as String, super.fromJson(json); @override diff --git a/lib/src/model/basic_room_event.dart b/lib/src/model/basic_room_event.dart index 0e416483..1771e2ca 100644 --- a/lib/src/model/basic_room_event.dart +++ b/lib/src/model/basic_room_event.dart @@ -36,7 +36,7 @@ class BasicRoomEvent extends BasicEvent { ); BasicRoomEvent.fromJson(Map json) - : roomId = json['room_id'], + : roomId = json['room_id'] as String?, super.fromJson(json); @override diff --git a/lib/src/model/children_state.dart b/lib/src/model/children_state.dart index ed0d6c26..03b0688b 100644 --- a/lib/src/model/children_state.dart +++ b/lib/src/model/children_state.dart @@ -39,8 +39,8 @@ class ChildrenState extends StrippedStateEvent { stateKey: stateKey); ChildrenState.fromJson(Map json) - : originServerTs = - DateTime.fromMillisecondsSinceEpoch(json['origin_server_ts']), + : originServerTs = DateTime.fromMillisecondsSinceEpoch( + json['origin_server_ts'] as int), super.fromJson(json); @override diff --git a/lib/src/model/events/image_pack_content.dart b/lib/src/model/events/image_pack_content.dart index 31923917..a7cbdf37 100644 --- a/lib/src/model/events/image_pack_content.dart +++ b/lib/src/model/events/image_pack_content.dart @@ -78,15 +78,19 @@ class ImagePackContent { (e) => !['images', 'pack', 'emoticons', 'short'].contains(e.key))), pack = ImagePackPackContent.fromJson( json.tryGetMap('pack') ?? {}), - images = json.tryGetMap('images')?.catchMap( - (k, v) => MapEntry(k, ImagePackImageContent.fromJson(v))) ?? + images = json.tryGetMap('images')?.catchMap((k, v) => + MapEntry( + k, + ImagePackImageContent.fromJson( + v as Map))) ?? // the "emoticons" key needs a small migration on the key, ":string:" --> "string" json.tryGetMap('emoticons')?.catchMap((k, v) => MapEntry( k.startsWith(':') && k.endsWith(':') ? k.substring(1, k.length - 1) : k, - ImagePackImageContent.fromJson(v))) ?? + ImagePackImageContent.fromJson( + v as Map))) ?? // the "short" key was still just a map from shortcode to mxc uri json.tryGetMap('short')?.catchMap((k, v) => MapEntry( @@ -118,7 +122,7 @@ class ImagePackImageContent { ImagePackImageContent.fromJson(Map json) : _json = Map.fromEntries(json.entries .where((e) => !['url', 'body', 'info'].contains(e.key))), - url = Uri.parse(json['url']), + url = Uri.parse(json['url'] as String), body = json.tryGet('body'), info = json.tryGetMap('info'), usage = imagePackUsageFromJson(json.tryGetList('usage')); diff --git a/lib/src/model/events/room_encrypted_content.dart b/lib/src/model/events/room_encrypted_content.dart index a358dc9f..48dc6e24 100644 --- a/lib/src/model/events/room_encrypted_content.dart +++ b/lib/src/model/events/room_encrypted_content.dart @@ -49,7 +49,8 @@ class RoomEncryptedContent { // filter out invalid/incomplete CiphertextInfos ciphertextOlm = json .tryGet>('ciphertext', TryGet.silent) - ?.catchMap((k, v) => MapEntry(k, CiphertextInfo.fromJson(v))); + ?.catchMap((k, v) => MapEntry( + k, CiphertextInfo.fromJson(v as Map))); Map toJson() { final data = {}; @@ -81,8 +82,8 @@ class CiphertextInfo { int type; CiphertextInfo.fromJson(Map json) - : body = json['body'], - type = json['type']; + : body = json['body'] as String, + type = json['type'] as int; Map toJson() { final data = {}; diff --git a/lib/src/model/matrix_event.dart b/lib/src/model/matrix_event.dart index 516f4b35..b0ed6ee7 100644 --- a/lib/src/model/matrix_event.dart +++ b/lib/src/model/matrix_event.dart @@ -50,13 +50,13 @@ class MatrixEvent extends StrippedStateEvent { stateKey: stateKey); MatrixEvent.fromJson(Map json) - : eventId = json['event_id'], - roomId = json['room_id'], - originServerTs = - DateTime.fromMillisecondsSinceEpoch(json['origin_server_ts']), + : eventId = json['event_id'] as String, + roomId = json['room_id'] as String?, + originServerTs = DateTime.fromMillisecondsSinceEpoch( + json['origin_server_ts'] as int), unsigned = (json['unsigned'] as Map?)?.copy(), prevContent = (json['prev_content'] as Map?)?.copy(), - redacts = json['redacts'], + redacts = json['redacts'] as String?, super.fromJson(json); @override diff --git a/lib/src/model/matrix_exception.dart b/lib/src/model/matrix_exception.dart index 94257427..e04aee1e 100644 --- a/lib/src/model/matrix_exception.dart +++ b/lib/src/model/matrix_exception.dart @@ -65,12 +65,12 @@ class MatrixException implements Exception { /// The unique identifier for this error. String get errcode => - raw['errcode'] ?? + raw['errcode'] as String? ?? (requireAdditionalAuthentication ? 'M_FORBIDDEN' : 'M_UNKNOWN'); /// A human readable error description. String get errorMessage => - raw['error'] ?? + raw['error'] as String? ?? (requireAdditionalAuthentication ? 'Require additional authentication' : 'Unknown error'); @@ -79,7 +79,7 @@ class MatrixException implements Exception { http.Response? response; MatrixException(http.Response this.response) - : raw = json.decode(response.body); + : raw = json.decode(response.body) as Map; MatrixException.fromJson(Map content) : raw = content; @@ -91,11 +91,11 @@ class MatrixException implements Exception { (e) => e.toString() == 'MatrixError.${(raw["errcode"] ?? "")}', orElse: () => MatrixError.M_UNKNOWN); - int? get retryAfterMs => raw['retry_after_ms']; + int? get retryAfterMs => raw['retry_after_ms'] as int?; /// This is a session identifier that the client must pass back to the homeserver, if one is provided, /// in subsequent attempts to authenticate in the same API call. - String? get session => raw['session']; + String? get session => raw['session'] as String?; /// Returns true if the server requires additional authentication. bool get requireAdditionalAuthentication => response != null @@ -119,11 +119,12 @@ class MatrixException implements Exception { /// This section contains any information that the client will need to know in order to use a given type /// of authentication. For each authentication type presented, that type may be present as a key in this /// dictionary. For example, the public part of an OAuth client ID could be given here. - Map? get authenticationParams => raw['params']; + Map? get authenticationParams => + raw['params'] as Map?; /// Returns the list of already completed authentication flows from previous requests. List get completedAuthenticationFlows => - List.from(raw['completed'] ?? []); + List.from(raw['completed'] as List? ?? []); } /// For each endpoint, a server offers one or more 'flows' that the client can use diff --git a/lib/src/model/matrix_keys.dart b/lib/src/model/matrix_keys.dart index 65f47368..432dccfc 100644 --- a/lib/src/model/matrix_keys.dart +++ b/lib/src/model/matrix_keys.dart @@ -21,7 +21,7 @@ * SOFTWARE. */ -import '../utils/map_copy_extension.dart'; +import 'package:matrix_api_lite/matrix_api_lite.dart'; abstract class MatrixSignableKey { String userId; @@ -39,14 +39,11 @@ abstract class MatrixSignableKey { MatrixSignableKey.fromJson(Map json) : _json = json, - userId = json['user_id'], - keys = Map.from(json['keys']), + userId = json['user_id'] as String, + keys = Map.from(json['keys'] as Map), // we need to manually copy to ensure that our map is Map> - signatures = json['signatures'] is Map - ? Map>.from((json['signatures'] as Map) - .map((k, v) => MapEntry(k, Map.from(v)))) - : null, - unsigned = (json['unsigned'] as Map?)?.copy(); + signatures = json.tryGetMap>('signatures'), + unsigned = json.tryGetMap('unsigned'); Map toJson() { final data = _json ?? {}; @@ -81,7 +78,7 @@ class MatrixCrossSigningKey extends MatrixSignableKey { @override MatrixCrossSigningKey.fromJson(Map json) - : usage = List.from(json['usage']), + : usage = json.tryGetList('usage') ?? [], super.fromJson(json); @override @@ -97,7 +94,7 @@ class MatrixDeviceKeys extends MatrixSignableKey { List algorithms; String? get deviceDisplayName => - unsigned != null ? unsigned!['device_display_name'] : null; + unsigned?.tryGet('device_display_name'); MatrixDeviceKeys( String userId, @@ -113,8 +110,8 @@ class MatrixDeviceKeys extends MatrixSignableKey { @override MatrixDeviceKeys.fromJson(Map json) - : algorithms = (json['algorithms'] as List).cast(), - deviceId = json['device_id'], + : algorithms = json.tryGetList('algorithms') ?? [], + deviceId = json['device_id'] as String, super.fromJson(json); @override diff --git a/lib/src/model/presence.dart b/lib/src/model/presence.dart index 73848c2e..37b33f3d 100644 --- a/lib/src/model/presence.dart +++ b/lib/src/model/presence.dart @@ -28,6 +28,7 @@ class Presence extends BasicEventWithSender { PresenceContent presence; Presence.fromJson(Map json) - : presence = PresenceContent.fromJson(json['content']), + : presence = + PresenceContent.fromJson(json['content'] as Map), super.fromJson(json); } diff --git a/lib/src/model/presence_content.dart b/lib/src/model/presence_content.dart index edf9a1de..8f80851e 100644 --- a/lib/src/model/presence_content.dart +++ b/lib/src/model/presence_content.dart @@ -21,7 +21,7 @@ * SOFTWARE. */ -import '../generated/model.dart'; +import 'package:matrix_api_lite/matrix_api_lite.dart'; class PresenceContent { PresenceType presence; @@ -32,9 +32,9 @@ class PresenceContent { PresenceContent.fromJson(Map json) : presence = PresenceType.values.firstWhere( (p) => p.toString().split('.').last == json['presence']), - lastActiveAgo = json['last_active_ago'], - statusMsg = json['status_msg'], - currentlyActive = json['currently_active']; + lastActiveAgo = json.tryGet('last_active_ago'), + statusMsg = json.tryGet('status_msg'), + currentlyActive = json.tryGet('currently_active'); Map toJson() { final data = {}; diff --git a/lib/src/model/room_keys_keys.dart b/lib/src/model/room_keys_keys.dart index 39df80b4..ce148bc1 100644 --- a/lib/src/model/room_keys_keys.dart +++ b/lib/src/model/room_keys_keys.dart @@ -21,6 +21,8 @@ * SOFTWARE. */ +import 'package:matrix_api_lite/matrix_api_lite.dart'; + class RoomKeysSingleKey { int firstMessageIndex; int forwardedCount; @@ -34,10 +36,10 @@ class RoomKeysSingleKey { required this.sessionData}); RoomKeysSingleKey.fromJson(Map json) - : firstMessageIndex = json['first_message_index'], - forwardedCount = json['forwarded_count'], - isVerified = json['is_verified'], - sessionData = json['session_data']; + : firstMessageIndex = json['first_message_index'] as int, + forwardedCount = json['forwarded_count'] as int, + isVerified = json['is_verified'] as bool, + sessionData = json['session_data'] as Map; Map toJson() { final data = {}; @@ -55,8 +57,8 @@ class RoomKeysRoom { RoomKeysRoom({required this.sessions}); RoomKeysRoom.fromJson(Map json) - : sessions = (json['sessions'] as Map) - .map((k, v) => MapEntry(k, RoomKeysSingleKey.fromJson(v))); + : sessions = (json['sessions'] as Map).map((k, v) => + MapEntry(k, RoomKeysSingleKey.fromJson(v as Map))); Map toJson() { final data = {}; @@ -70,8 +72,9 @@ class RoomKeysUpdateResponse { int count; RoomKeysUpdateResponse.fromJson(Map json) - : etag = json['etag'], // synapse replies an int but docs say string? - count = json['count']; + : etag = json.tryGet('etag') ?? + '', // synapse replies an int but docs say string? + count = json.tryGet('count') ?? 0; Map toJson() { final data = {}; diff --git a/lib/src/model/room_summary.dart b/lib/src/model/room_summary.dart index 1947d829..0f19836d 100644 --- a/lib/src/model/room_summary.dart +++ b/lib/src/model/room_summary.dart @@ -28,10 +28,10 @@ class RoomSummary { RoomSummary.fromJson(Map json) : mHeroes = json['m.heroes'] != null - ? List.from(json['m.heroes']) + ? List.from(json['m.heroes'] as List) : null, - mJoinedMemberCount = json['m.joined_member_count'], - mInvitedMemberCount = json['m.invited_member_count']; + mJoinedMemberCount = json['m.joined_member_count'] as int?, + mInvitedMemberCount = json['m.invited_member_count'] as int?; Map toJson() { final data = {}; diff --git a/lib/src/model/stripped_state_event.dart b/lib/src/model/stripped_state_event.dart index 20bd4927..9fbabb37 100644 --- a/lib/src/model/stripped_state_event.dart +++ b/lib/src/model/stripped_state_event.dart @@ -21,7 +21,7 @@ * SOFTWARE. */ -import 'basic_event_with_sender.dart'; +import 'package:matrix_api_lite/matrix_api_lite.dart'; class StrippedStateEvent extends BasicEventWithSender { String? stateKey; @@ -34,7 +34,7 @@ class StrippedStateEvent extends BasicEventWithSender { : super(type: type, content: content, senderId: senderId); StrippedStateEvent.fromJson(Map json) - : stateKey = json['state_key'], + : stateKey = json.tryGet('state_key'), super.fromJson(json); @override diff --git a/lib/src/model/sync_update.dart b/lib/src/model/sync_update.dart index e1e7da52..a435894a 100644 --- a/lib/src/model/sync_update.dart +++ b/lib/src/model/sync_update.dart @@ -21,13 +21,7 @@ * SOFTWARE. */ -import 'basic_event.dart'; -import 'basic_event_with_sender.dart'; -import 'basic_room_event.dart'; -import 'matrix_event.dart'; -import 'presence.dart'; -import 'room_summary.dart'; -import 'stripped_state_event.dart'; +import 'package:matrix_api_lite/matrix_api_lite.dart'; class SyncUpdate { String nextBatch; @@ -51,32 +45,34 @@ class SyncUpdate { }); SyncUpdate.fromJson(Map json) - : nextBatch = json['next_batch'], - rooms = - json['rooms'] != null ? RoomsUpdate.fromJson(json['rooms']) : null, - presence = ((json['presence'] as Map?)?['events'] as List?) - ?.map((i) => Presence.fromJson(i)) + : nextBatch = json['next_batch'] as String, + rooms = (() { + final temp = json.tryGetMap('rooms'); + return temp != null ? RoomsUpdate.fromJson(temp) : null; + }()), + presence = json + .tryGetMap>('presence')?['events'] + ?.map((i) => Presence.fromJson(i as Map)) .toList(), - accountData = ((json['account_data'] as Map?)?['events'] as List?) - ?.map((i) => BasicEvent.fromJson(i)) + accountData = json + .tryGetMap>('account_data')?['events'] + ?.map((i) => BasicEvent.fromJson(i as Map)) .toList(), - toDevice = ((json['to_device'] as Map?)?['events'] as List?) - ?.map((i) => BasicEventWithSender.fromJson(i)) + toDevice = json + .tryGetMap>('to_device')?['events'] + ?.map( + (i) => BasicEventWithSender.fromJson(i as Map)) .toList(), - deviceLists = json['device_lists'] != null - ? DeviceListsUpdate.fromJson(json['device_lists']) - : null, - deviceOneTimeKeysCount = json['device_one_time_keys_count'] != null - ? Map.from(json['device_one_time_keys_count']) - : null, - deviceUnusedFallbackKeyTypes = (json[ - 'device_unused_fallback_key_types'] ?? - json[ - 'org.matrix.msc2732.device_unused_fallback_key_types']) != - null - ? List.from(json['device_unused_fallback_key_types'] ?? - json['org.matrix.msc2732.device_unused_fallback_key_types']) - : null; + deviceLists = (() { + final temp = json.tryGetMap('device_lists'); + return temp != null ? DeviceListsUpdate.fromJson(temp) : null; + }()), + deviceOneTimeKeysCount = + json.tryGetMap('device_one_time_keys_count'), + deviceUnusedFallbackKeyTypes = + json.tryGetList('device_unused_fallback_key_types') ?? + json.tryGetList( + 'org.matrix.msc2732.device_unused_fallback_key_types'); Map toJson() { final data = {}; @@ -126,18 +122,12 @@ class RoomsUpdate { }); RoomsUpdate.fromJson(Map json) { - join = json['join'] != null - ? (json['join'] as Map) - .map((k, v) => MapEntry(k, JoinedRoomUpdate.fromJson(v))) - : null; - invite = json['invite'] != null - ? (json['invite'] as Map) - .map((k, v) => MapEntry(k, InvitedRoomUpdate.fromJson(v))) - : null; - leave = json['leave'] != null - ? (json['leave'] as Map) - .map((k, v) => MapEntry(k, LeftRoomUpdate.fromJson(v))) - : null; + join = json.tryGetMap('join')?.catchMap((k, v) => + MapEntry(k, JoinedRoomUpdate.fromJson(v as Map))); + invite = json.tryGetMap('invite')?.catchMap((k, v) => + MapEntry(k, InvitedRoomUpdate.fromJson(v as Map))); + leave = json.tryGetMap('leave')?.catchMap((k, v) => + MapEntry(k, LeftRoomUpdate.fromJson(v as Map))); } Map toJson() { @@ -175,24 +165,22 @@ class JoinedRoomUpdate extends SyncRoomUpdate { }); JoinedRoomUpdate.fromJson(Map json) - : summary = json['summary'] != null - ? RoomSummary.fromJson(json['summary']) - : null, - state = ((json['state'] as Map?)?['events'] as List?) - ?.map((i) => MatrixEvent.fromJson(i)) + : summary = json.tryGetFromJson('summary', RoomSummary.fromJson), + state = json + .tryGetMap>('state')?['events'] + ?.map((i) => MatrixEvent.fromJson(i as Map)) .toList(), - timeline = json['timeline'] != null - ? TimelineUpdate.fromJson(json['timeline']) - : null, - ephemeral = ((json['ephemeral'] as Map?)?['events'] as List?) - ?.map((i) => BasicRoomEvent.fromJson(i)) + timeline = json.tryGetFromJson('timeline', TimelineUpdate.fromJson), + ephemeral = json + .tryGetMap>('ephemeral')?['events'] + ?.map((i) => BasicRoomEvent.fromJson(i as Map)) .toList(), - accountData = ((json['account_data'] as Map?)?['events'] as List?) - ?.map((i) => BasicRoomEvent.fromJson(i)) + accountData = json + .tryGetMap>('account_data')?['events'] + ?.map((i) => BasicRoomEvent.fromJson(i as Map)) .toList(), - unreadNotifications = json['unread_notifications'] != null - ? UnreadNotificationCounts.fromJson(json['unread_notifications']) - : null; + unreadNotifications = json.tryGetFromJson( + 'unread_notifications', UnreadNotificationCounts.fromJson); Map toJson() { final data = {}; @@ -230,8 +218,9 @@ class InvitedRoomUpdate extends SyncRoomUpdate { InvitedRoomUpdate({this.inviteState}); InvitedRoomUpdate.fromJson(Map json) - : inviteState = ((json['invite_state'] as Map?)?['events'] as List?) - ?.map((i) => StrippedStateEvent.fromJson(i)) + : inviteState = json + .tryGetMap>('invite_state')?['events'] + ?.map((i) => StrippedStateEvent.fromJson(i as Map)) .toList(); Map toJson() { @@ -257,14 +246,14 @@ class LeftRoomUpdate extends SyncRoomUpdate { }); LeftRoomUpdate.fromJson(Map json) - : state = ((json['state'] as Map?)?['events'] as List?) - ?.map((i) => MatrixEvent.fromJson(i)) + : state = json + .tryGetMap>('state')?['events'] + ?.map((i) => MatrixEvent.fromJson(i as Map)) .toList(), - timeline = json['timeline'] != null - ? TimelineUpdate.fromJson(json['timeline']) - : null, - accountData = ((json['account_data'] as Map?)?['events'] as List?) - ?.map((i) => BasicRoomEvent.fromJson(i)) + timeline = json.tryGetFromJson('timeline', TimelineUpdate.fromJson), + accountData = json + .tryGetMap>('account_data')?['events'] + ?.map((i) => BasicRoomEvent.fromJson(i as Map)) .toList(); Map toJson() { @@ -297,13 +286,13 @@ class TimelineUpdate { this.prevBatch, }); - TimelineUpdate.fromJson(Map json) { - events = json['events'] != null - ? (json['events'] as List).map((i) => MatrixEvent.fromJson(i)).toList() - : null; - limited = json['limited']; - prevBatch = json['prev_batch']; - } + TimelineUpdate.fromJson(Map json) + : events = json + .tryGetList>('events') + ?.map((v) => MatrixEvent.fromJson(v)) + .toList(), + limited = json.tryGet('limited'), + prevBatch = json.tryGet('prev_batch'); Map toJson() { final data = {}; @@ -329,10 +318,9 @@ class UnreadNotificationCounts { this.highlightCount, }); - UnreadNotificationCounts.fromJson(Map json) { - highlightCount = json['highlight_count']; - notificationCount = json['notification_count']; - } + UnreadNotificationCounts.fromJson(Map json) + : highlightCount = json.tryGet('highlight_count'), + notificationCount = json.tryGet('notification_count'); Map toJson() { final data = {}; @@ -355,10 +343,9 @@ class DeviceListsUpdate { this.left, }); - DeviceListsUpdate.fromJson(Map json) { - changed = List.from(json['changed'] ?? []); - left = List.from(json['left'] ?? []); - } + DeviceListsUpdate.fromJson(Map json) + : changed = json.tryGetList('changed') ?? [], + left = json.tryGetList('left') ?? []; Map toJson() { final data = {}; diff --git a/lib/src/utils/try_get_map_extension.dart b/lib/src/utils/try_get_map_extension.dart index fbaa7e11..02dc2743 100644 --- a/lib/src/utils/try_get_map_extension.dart +++ b/lib/src/utils/try_get_map_extension.dart @@ -100,6 +100,13 @@ extension TryGetMapExtension on Map { return null; } } + + A? tryGetFromJson(String key, A Function(Map) fromJson, + [TryGet log = TryGet.optional]) { + final value = tryGetMap(key, log); + + return value != null ? fromJson(value) : null; + } } extension on StackTrace { diff --git a/test/event_content_test.dart b/test/event_content_test.dart index 0c5ede11..3b5bf6d4 100644 --- a/test/event_content_test.dart +++ b/test/event_content_test.dart @@ -43,7 +43,7 @@ void main() { 'type': 'm.room.encryption', 'unsigned': {'age': 1234} }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(MatrixEvent.fromJson(json!).parsedRoomEncryptionContent.toJson(), json['content']); }); @@ -63,7 +63,7 @@ void main() { 'type': 'm.room.encrypted', 'unsigned': {'age': 1234} }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(MatrixEvent.fromJson(json!).parsedRoomEncryptedContent.toJson(), json['content']); json = { @@ -84,7 +84,7 @@ void main() { 'type': 'm.room.encrypted', 'unsigned': {'age': 1234} }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(MatrixEvent.fromJson(json!).parsedRoomEncryptedContent.toJson(), json['content']); }); @@ -98,7 +98,7 @@ void main() { }, 'type': 'm.room_key' }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(BasicEvent.fromJson(json!).parsedRoomKeyContent.toJson(), json['content']); }); @@ -111,7 +111,7 @@ void main() { }, 'type': 'm.room_key_request' }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(BasicEvent.fromJson(json!).parsedRoomKeyRequestContent.toJson(), json['content']); json = { @@ -128,7 +128,7 @@ void main() { }, 'type': 'm.room_key_request' }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(BasicEvent.fromJson(json!).parsedRoomKeyRequestContent.toJson(), json['content']); }); @@ -148,7 +148,7 @@ void main() { }, 'type': 'm.forwarded_room_key' }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(BasicEvent.fromJson(json!).parsedForwardedRoomKeyContent.toJson(), json['content']); }); @@ -164,7 +164,7 @@ void main() { 'recipient_keys': {'ed25519': ''}, 'keys': {'ed25519': ''} }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map?; expect(OlmPlaintextPayload.fromJson(json!).toJson(), json); }); test('Image Pack Content', () { @@ -190,7 +190,7 @@ void main() { 'org.custom': 'blah', }, }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map; expect(BasicEvent.fromJson(json).parsedImagePackContent.toJson(), json['content']); @@ -205,7 +205,7 @@ void main() { }, }, }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map; expect( BasicEvent.fromJson(json) .parsedImagePackContent @@ -223,7 +223,7 @@ void main() { }, }, }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map; expect( BasicEvent.fromJson(json) .parsedImagePackContent @@ -242,7 +242,7 @@ void main() { }, }, }; - json = jsonDecode(jsonEncode(json)); + json = jsonDecode(jsonEncode(json)) as Map; expect(BasicEvent.fromJson(json).parsedImagePackContent.images['emote'], null); });