diff --git a/gradle.properties b/gradle.properties index f23a194d11..2f911f8bab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ klock_version=2.0.3 uuid_version=0.2.3 ktor_version=1.5.0 -micro_utils_version=0.4.19 +micro_utils_version=0.4.20 javax_activation_version=1.1.1 diff --git a/tgbotapi.core/build.gradle b/tgbotapi.core/build.gradle index 7ba634fb89..d38ff75ff5 100644 --- a/tgbotapi.core/build.gradle +++ b/tgbotapi.core/build.gradle @@ -48,6 +48,7 @@ kotlin { api "dev.inmo:micro_utils.coroutines:$micro_utils_version" api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version" + api "dev.inmo:micro_utils.serialization.encapsulator:$micro_utils_version" api "io.ktor:ktor-client-core:$ktor_version" } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt index b149eba867..5499e76b22 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/passport/encrypted_data/EncryptedElementSerializer.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.types.passport.encrypted_data +import dev.inmo.micro_utils.serialization.encapsulator.Encapsulator import dev.inmo.tgbotapi.types.hashField import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.EncryptedPassportElement import dev.inmo.tgbotapi.types.passport.encrypted_data.abstracts.UnknownEncryptedPassportElement @@ -12,6 +13,22 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.* +val encryptedElementsClassesByTypes = mapOf( + "personal_details" to Encapsulator(EncryptedPersonalDetails::class, EncryptedPersonalDetails.serializer()), + "passport" to Encapsulator(CommonPassport::class, CommonPassport.serializer()), + "driver_license" to Encapsulator(DriverLicense::class, DriverLicense.serializer()), + "identity_card" to Encapsulator(IdentityCard::class, IdentityCard.serializer()), + "internal_passport" to Encapsulator(InternalPassport::class, InternalPassport.serializer()), + "address" to Encapsulator(EncryptedAddress::class, EncryptedAddress.serializer()), + "utility_bill" to Encapsulator(UtilityBill::class, UtilityBill.serializer()), + "bank_statement" to Encapsulator(BankStatement::class, BankStatement.serializer()), + "rental_agreement" to Encapsulator(RentalAgreement::class, RentalAgreement.serializer()), + "passport_registration" to Encapsulator(PassportRegistration::class, PassportRegistration.serializer()), + "temporary_registration" to Encapsulator(TemporaryRegistration::class, TemporaryRegistration.serializer()), + "phone_number" to Encapsulator(PhoneNumber::class, PhoneNumber.serializer()), + "email" to Encapsulator(Email::class, Email.serializer()) +) + @Serializer(EncryptedPassportElement::class) object EncryptedElementSerializer : KSerializer { private val jsonSerializer = JsonObject.serializer() @@ -19,69 +36,23 @@ object EncryptedElementSerializer : KSerializer { override fun deserialize(decoder: Decoder): EncryptedPassportElement { val json = jsonSerializer.deserialize(decoder) - return when (json[typeField] ?.jsonPrimitive ?.content) { - "personal_details" -> nonstrictJsonFormat.decodeFromJsonElement(EncryptedPersonalDetails.serializer(), json) - "passport" -> nonstrictJsonFormat.decodeFromJsonElement(CommonPassport.serializer(), json) - "driver_license" -> nonstrictJsonFormat.decodeFromJsonElement(DriverLicense.serializer(), json) - "identity_card" -> nonstrictJsonFormat.decodeFromJsonElement(IdentityCard.serializer(), json) - "internal_passport" -> nonstrictJsonFormat.decodeFromJsonElement(InternalPassport.serializer(), json) - "address" -> nonstrictJsonFormat.decodeFromJsonElement(EncryptedAddress.serializer(), json) - "utility_bill" -> nonstrictJsonFormat.decodeFromJsonElement(UtilityBill.serializer(), json) - "bank_statement" -> nonstrictJsonFormat.decodeFromJsonElement(BankStatement.serializer(), json) - "rental_agreement" -> nonstrictJsonFormat.decodeFromJsonElement(RentalAgreement.serializer(), json) - "passport_registration" -> nonstrictJsonFormat.decodeFromJsonElement(PassportRegistration.serializer(), json) - "temporary_registration" -> nonstrictJsonFormat.decodeFromJsonElement(TemporaryRegistration.serializer(), json) - "phone_number" -> nonstrictJsonFormat.decodeFromJsonElement(PhoneNumber.serializer(), json) - "email" -> nonstrictJsonFormat.decodeFromJsonElement(Email.serializer(), json) - else -> UnknownEncryptedPassportElement(json, json[hashField] ?.jsonPrimitive ?.content ?: "") - } + return json[typeField] ?.jsonPrimitive ?.content ?.let { type -> + encryptedElementsClassesByTypes[type] ?.serializer ?.let { deserializer -> + nonstrictJsonFormat.decodeFromJsonElement(deserializer, json) + } + } ?: UnknownEncryptedPassportElement(json, json[hashField] ?.jsonPrimitive ?.content ?: "") } override fun serialize(encoder: Encoder, value: EncryptedPassportElement) { - val json = when (value) { - is EncryptedPersonalDetails -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(EncryptedPersonalDetails.serializer(), value).jsonObject + (typeField to JsonPrimitive("personal_details")) - ) - is CommonPassport -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(CommonPassport.serializer(), value).jsonObject + (typeField to JsonPrimitive("passport")) - ) - is DriverLicense -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(DriverLicense.serializer(), value).jsonObject + (typeField to JsonPrimitive("driver_license")) - ) - is IdentityCard -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(IdentityCard.serializer(), value).jsonObject + (typeField to JsonPrimitive("identity_card")) - ) - is InternalPassport -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(InternalPassport.serializer(), value).jsonObject + (typeField to JsonPrimitive("internal_passport")) - ) - is EncryptedAddress -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(EncryptedAddress.serializer(), value).jsonObject + (typeField to JsonPrimitive("address")) - ) - is UtilityBill -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(UtilityBill.serializer(), value).jsonObject + (typeField to JsonPrimitive("utility_bill")) - ) - is BankStatement -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(BankStatement.serializer(), value).jsonObject + (typeField to JsonPrimitive("bank_statement")) - ) - is RentalAgreement -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(RentalAgreement.serializer(), value).jsonObject + (typeField to JsonPrimitive("rental_agreement")) - ) - is PassportRegistration -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(PassportRegistration.serializer(), value).jsonObject + (typeField to JsonPrimitive("passport_registration")) - ) - is TemporaryRegistration -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(TemporaryRegistration.serializer(), value).jsonObject + (typeField to JsonPrimitive("temporary_registration")) - ) - is PhoneNumber -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(PhoneNumber.serializer(), value).jsonObject + (typeField to JsonPrimitive("phone_number")) - ) - is Email -> JsonObject( - nonstrictJsonFormat.encodeToJsonElement(Email.serializer(), value).jsonObject + (typeField to JsonPrimitive("email")) - ) - is UnknownEncryptedPassportElement -> value.rawJson - else -> return + val json = value.let { + encryptedElementsClassesByTypes.forEach { (key, encapsulator) -> + val json = encapsulator.encapsulate(value) { data -> + nonstrictJsonFormat.encodeToJsonElement(this as KSerializer, data).jsonObject + } ?: return@forEach + return@let JsonObject(json + (typeField to JsonPrimitive(key))) + } + (value as? UnknownEncryptedPassportElement) ?.rawJson ?: return } jsonSerializer.serialize(encoder, json) } - }