Про то, как AI не смог
Jazari One — приложение со стейблкоинами. Один из важных типов — Money, работает поверх java.util.Currency. Но старая реализация не подходит: вызов Currency.getInstance("USDT") просто бросил бы исключение.
Нужно было расширить тип, чтобы он умел работать и с фиатом, и с токенами.
sealed interface MoneyCurrency {
val currencyCode: String
data class Fiat(val currency: Currency) : MoneyCurrency { ... }
data class Token(val symbol: String) : MoneyCurrency { ... }
}
Вопрос был один: как определить, что перед нами — фиат или токен? AI решил проверять длину строки: USD — три символа, USDT — четыре. Звучит правдоподобно ровно до момента, когда вспоминаешь про BTC, SOL, ETH или стейблкоин DAI.
Следующая идея от AI — делегировать Java:
fun fromCode(code: String): MoneyCurrency {
return try {
Fiat(Currency.getInstance(code))
} catch (e: IllegalArgumentException) {
Token(code)
}
}
Currency.getInstance() знает все ISO 4217 коды. Не знает — значит, токен. Выглядит элегантно.
Тут сразу две проблемы:
• исключение — это слишком медленно. Выбросить исключения в разы или десятки раз медленнее возврата результата
• на Android есть нюанс: ICU добавляет некоторые трёхсимвольные криптовалюты — в частности, ETH и BTC — как «настоящие» валюты, просто с numericCode == -1. Поэтому Currency.getInstance("ETH") не бросает исключение, и ETH молча стал бы фиатом.
🫴 Финальное решение — явно фильтровать по numericCode (на скрине), который соответствует ISO 4217:
private val fiatCurrencies: Map by lazy {
Currency.getAvailableCurrencies()
.filter { it.numericCode > 0 }
.associateBy { it.currencyCode }
}
fun fromCode(code: String): MoneyCurrency {
val currency = fiatCurrencies[code]
return if (currency != null) Fiat(currency) else Token(code)
}
Набор фиатных валют строится один раз, лениво. ETH и BTC учитаны. Определение типа валюты — O(1)
Три попытки ушло у AI, чтобы написать одну функцию. Не забывайте проверять за AI
→ серия «Два приложения — один логин»
#android #kotlin #androiddev #архитектура
Jazari One — приложение со стейблкоинами. Один из важных типов — Money, работает поверх java.util.Currency. Но старая реализация не подходит: вызов Currency.getInstance("USDT") просто бросил бы исключение.
Нужно было расширить тип, чтобы он умел работать и с фиатом, и с токенами.
sealed interface MoneyCurrency {
val currencyCode: String
data class Fiat(val currency: Currency) : MoneyCurrency { ... }
data class Token(val symbol: String) : MoneyCurrency { ... }
}
Вопрос был один: как определить, что перед нами — фиат или токен? AI решил проверять длину строки: USD — три символа, USDT — четыре. Звучит правдоподобно ровно до момента, когда вспоминаешь про BTC, SOL, ETH или стейблкоин DAI.
Следующая идея от AI — делегировать Java:
fun fromCode(code: String): MoneyCurrency {
return try {
Fiat(Currency.getInstance(code))
} catch (e: IllegalArgumentException) {
Token(code)
}
}
Currency.getInstance() знает все ISO 4217 коды. Не знает — значит, токен. Выглядит элегантно.
Тут сразу две проблемы:
• исключение — это слишком медленно. Выбросить исключения в разы или десятки раз медленнее возврата результата
• на Android есть нюанс: ICU добавляет некоторые трёхсимвольные криптовалюты — в частности, ETH и BTC — как «настоящие» валюты, просто с numericCode == -1. Поэтому Currency.getInstance("ETH") не бросает исключение, и ETH молча стал бы фиатом.
🫴 Финальное решение — явно фильтровать по numericCode (на скрине), который соответствует ISO 4217:
private val fiatCurrencies: Map by lazy {
Currency.getAvailableCurrencies()
.filter { it.numericCode > 0 }
.associateBy { it.currencyCode }
}
fun fromCode(code: String): MoneyCurrency {
val currency = fiatCurrencies[code]
return if (currency != null) Fiat(currency) else Token(code)
}
Набор фиатных валют строится один раз, лениво. ETH и BTC учитаны. Определение типа валюты — O(1)
Три попытки ушло у AI, чтобы написать одну функцию. Не забывайте проверять за AI
→ серия «Два приложения — один логин»
#android #kotlin #androiddev #архитектура