Assim que começei a realizar o curso, existe muita repetição de código como a possibilidade do uso de alguns códigos em outras areas sendo que é possivel criar um arquivo Utils ou Extension Functions contendo a boa parte dos codigos repetidos como funçao na tentativa de evitar repetiçao e facilitar na programaçao qual so ocorre no final do curso. Portanto, eu criei algumas pequenas funções Genericas como Extension Functions com base na necessidade e no curso.
package br.com.alura.games.utils
import org.springframework.util.StringUtils
import java.math.BigDecimal
import java.time.LocalDate
import java.time.Period
import java.time.format.DateTimeFormatter
import kotlin.random.Random
import kotlin.reflect.full.memberProperties
fun String.getAge(): Int {
val pattern = "dd/MM/yyyy"
try {
val formatter = DateTimeFormatter.ofPattern(pattern)
val dataNascimento = LocalDate.parse(this, formatter)
return Period.between(dataNascimento, LocalDate.now()).years
}catch (ex: Exception){
throw Exception(
"Não foi possivel converter \"$this\" em idade.\n" +
"Formato obrigatorio: $pattern"
)
}
}
inline fun <reified T : Any> T.toStr(vararg exceptParams: String): String {
val properties = T::class.memberProperties
if (properties.isEmpty()) return "$this"
return properties
.filterNot { it.name in exceptParams }
.joinToString("\n") { prop ->
val value = prop.get(this)
"(${value?.javaClass?.simpleName}) ${prop.name}: $value"
}
}
inline fun <reified T:Any> T.toStrCapitalize(vararg exceptParams:String): String {
val properties = T::class.memberProperties
if (properties.isEmpty()) return "$this"
return properties
.filterNot { it.name in exceptParams }
.joinToString("\n") { prop ->
val value = prop.get(this)
"(${value?.javaClass?.simpleName}) ${StringUtils.capitalize(prop.name)}: $value"
}
}
inline fun <reified T> input(text: String, lowercase: Boolean = false): T {
print(if (!text.endsWith("\n") && !text.endsWith(" ")) "$text " else text)
val result = readLine() ?: ""
return when (T::class) {
BigDecimal::class -> result.toBigDecimal() as T
Double::class -> result.toDouble() as T
Float::class -> result.toFloat() as T
Byte::class -> result.toByte() as T
Short::class -> result.toShort() as T
Int::class -> result.toInt() as T
Long::class -> result.toLong() as T
Boolean::class -> toBoolean(result) as T
String::class -> (if (lowercase) result.lowercase() else result) as T
Any::class -> result as T
else -> {
throw Exception("Tipo não suportado")
}
}
}
fun inputConfirm(text: String): Boolean {
val answer: String = input(text, true)
return (answer == "s" || answer == "sim")
}
fun toBoolean(str: String): Boolean? {
val expr = str.trim().lowercase()
return when {
expr == "true" || expr == "t" -> true
expr == "false" || expr == "f" -> false
else -> throw IllegalArgumentException("Não é possível converter para Boolean")
}
}
fun validateEmail(email: String): Boolean {
val regex = Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}")
return regex.matches(email)
}
fun numTag(max: Int): String {
val num = Random.nextInt(max)
return String.format("%04d", num)
}
Exemplo de uso
package br.com.alura.alugames.principal
import br.com.alura.alugames.modelo.Jogo
import br.com.alura.alugames.servicos.CheapSharkAPI
import br.com.alura.games.modelo.Player
import br.com.alura.games.utils.*
fun main() {
var player = Player.build()
println(player.toStr())
do {
val searchId: String = input("Digite um código de jogo para buscar:")
val gameInfo = CheapSharkAPI().buscaJogo(searchId)
var game: Jogo = Jogo(gameInfo)
if (inputConfirm("Deseja inserir uma descrição personalizada? (S/N):")) {
game.addDescription()
} else {
game.descricao = game.titulo
}
println("${game.toStr()}\n")
} while (inputConfirm("Continuar procurando? (S/N):"))
println("Jogos Procurados:\n")
Jogo.jogos.forEach {
println("${it.toStr("capa")}'\n") // o campo capa esta sendo ignorado ao mostrar os campos.
}
}