diff --git a/lib/src/model/events/room_encrypted_content.dart b/lib/src/model/events/room_encrypted_content.dart index 060c328e..4f689566 100644 --- a/lib/src/model/events/room_encrypted_content.dart +++ b/lib/src/model/events/room_encrypted_content.dart @@ -47,12 +47,12 @@ class RoomEncryptedContent { RoomEncryptedContent.fromJson(Map json) : algorithm = json.tryGet('algorithm') ?? '', senderKey = json.tryGet('sender_key') ?? '', - deviceId = json.tryGet('device_id'), - sessionId = json.tryGet('session_id'), - ciphertextMegolm = json.silentTryGet('ciphertext'), + deviceId = json.tryGet('device_id', TryGet.optional), + sessionId = json.tryGet('session_id', TryGet.optional), + ciphertextMegolm = json.tryGet('ciphertext', TryGet.silent), // filter out invalid/incomplete CiphertextInfos ciphertextOlm = json - .silentTryGet>('ciphertext') + .tryGet>('ciphertext', TryGet.silent) ?.entries .map((e) { try { diff --git a/lib/src/model/events/room_encryption_content.dart b/lib/src/model/events/room_encryption_content.dart index b88db983..41173856 100644 --- a/lib/src/model/events/room_encryption_content.dart +++ b/lib/src/model/events/room_encryption_content.dart @@ -36,8 +36,9 @@ class RoomEncryptionContent { RoomEncryptionContent.fromJson(Map json) : algorithm = json.tryGet('algorithm') ?? '', - rotationPeriodMs = json.tryGet('rotation_period_ms'), - rotationPeriodMsgs = json.tryGet('rotation_period_msgs'); + rotationPeriodMs = json.tryGet('rotation_period_ms', TryGet.optional), + rotationPeriodMsgs = + json.tryGet('rotation_period_msgs', TryGet.optional); Map toJson() { final data = {}; diff --git a/lib/src/model/events/room_key_request_content.dart b/lib/src/model/events/room_key_request_content.dart index e03deed3..53f5597d 100644 --- a/lib/src/model/events/room_key_request_content.dart +++ b/lib/src/model/events/room_key_request_content.dart @@ -37,7 +37,7 @@ class RoomKeyRequestContent { RoomKeyRequestContent.fromJson(Map json) : body = ((x) => x != null ? RequestedKeyInfo.fromJson(x) : null)( - json.tryGet('body')), + json.tryGet('body', TryGet.optional)), action = json.tryGet('action') ?? '', requestingDeviceId = json.tryGet('requesting_device_id') ?? '', requestId = json.tryGet('request_id') ?? ''; diff --git a/lib/src/model/events/secret_storage_key_content.dart b/lib/src/model/events/secret_storage_key_content.dart index a10b3a06..de42a723 100644 --- a/lib/src/model/events/secret_storage_key_content.dart +++ b/lib/src/model/events/secret_storage_key_content.dart @@ -38,12 +38,11 @@ class SecretStorageKeyContent { SecretStorageKeyContent(); SecretStorageKeyContent.fromJson(Map json) - : passphrase = json['passphrase'] is Map - ? PassphraseInfo.fromJson(json['passphrase']) - : null, - iv = json.tryGet('iv'), - mac = json.tryGet('mac'), - algorithm = json.tryGet('algorithm'); + : passphrase = ((x) => x != null ? PassphraseInfo.fromJson(x) : null)( + json.tryGet('passphrase', TryGet.optional)), + iv = json.tryGet('iv', TryGet.optional), + mac = json.tryGet('mac', TryGet.optional), + algorithm = json.tryGet('algorithm', TryGet.optional); Map toJson() { final data = {}; @@ -73,7 +72,7 @@ class PassphraseInfo { : algorithm = json.tryGet('algorithm'), salt = json.tryGet('salt'), iterations = json.tryGet('iterations'), - bits = json.tryGet('bits'); + bits = json.tryGet('bits', TryGet.optional); 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 41d0c768..5726f63c 100644 --- a/lib/src/utils/try_get_map_extension.dart +++ b/lib/src/utils/try_get_map_extension.dart @@ -25,33 +25,54 @@ import 'dart:core'; import 'logs.dart'; -extension TryGetMapExtension on Map { - T? tryGet(String key) { - final Object? value = this[key]; - if (value is! T) { - Logs().w( - 'Expected "$T" in event content for the Key "$key" but got "${value.runtimeType}".'); - return null; - } - return value; - } +abstract class TryGet { + void call(String key, Type expected, Type actual); + + static const TryGet required = _RequiredLog(); + static const TryGet optional = _OptionalLog(); - /// Same as tryGet but without logging any warnings. /// This is helpful if you have a field that can mean multiple things on purpose. - T? silentTryGet(String key) { + static const TryGet silent = _SilentLog(); +} + +class _RequiredLog implements TryGet { + const _RequiredLog(); + @override + void call(String key, Type expected, Type actual) => Logs().w( + 'Expected "$expected" in event content for the Key "$key" but got "$actual".'); +} + +class _OptionalLog implements TryGet { + const _OptionalLog(); + @override + void call(String key, Type expected, Type actual) { + if (actual != Null) { + Logs().w( + 'Expected "$expected" in event content for the Key "$key" but got "$actual".'); + } + } +} + +class _SilentLog implements TryGet { + const _SilentLog(); + @override + void call(String key, Type expected, Type actual) {} +} + +extension TryGetMapExtension on Map { + T? tryGet(String key, [TryGet log = TryGet.required]) { final Object? value = this[key]; if (value is! T) { + log(key, T, value.runtimeType); return null; } return value; } - List? tryGetList(String key) { + List? tryGetList(String key, [TryGet log = TryGet.required]) { final Object? value = this[key]; if (value is! List) { - Logs().w( - 'Expected "List<$T>" in event content for the key "$key" but got "${value.runtimeType}".', - StackTrace.current); + log(key, T, value.runtimeType); return null; } try { @@ -64,11 +85,10 @@ extension TryGetMapExtension on Map { } } - Map? tryGetMap(String key) { + Map? tryGetMap(String key, [TryGet log = TryGet.required]) { final Object? value = this[key]; if (value is! Map) { - Logs().w( - 'Expected "Map<$A,$B>" in event content for the key "$key" but got "${value.runtimeType}".'); + log(key, {}.runtimeType, value.runtimeType); return null; } try {