Last active
June 11, 2020 21:23
-
-
Save j-didi/a18c65a42b0c0c28f255df76c618fc3b to your computer and use it in GitHub Desktop.
Kotlin Domain Specific Language using reflections, infix and aggregation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.gson.GsonBuilder | |
import kotlin.reflect.KMutableProperty | |
import kotlin.reflect.full.memberProperties | |
//Enum and properties to better infix semantic | |
private const val Terminal = 0 | |
enum class LogTarget(val value: Int) { | |
TERMINAL(0); | |
companion object { | |
fun fromInt(value: Int) = values().first { it.value == value } | |
} | |
} | |
//Data classes | |
data class PersonalInfo( | |
val name: String, | |
val email: String, | |
val phone: String, | |
val cpf: String | |
) | |
data class Address( | |
val cep: String, | |
val uf: String, | |
val city: String, | |
val district: String, | |
val street: String, | |
val number: String? = null, | |
val complement: String? = null | |
) | |
data class Account( | |
var id: Int, | |
var personalInfo: PersonalInfo? = null, | |
var address: Address? = null | |
) { | |
//Infix with reflection and aggregation | |
infix fun<TEntity> add(field: TEntity) where TEntity : Any { | |
Account::class.memberProperties | |
.filter{ it.name.equals(field::class.simpleName, true) } | |
.filterIsInstance<KMutableProperty<*>>() | |
.forEach { it.setter.call(this, field) } | |
} | |
//Formatted json log | |
infix fun logTo(target: Int) { | |
val logTarget = LogTarget.fromInt(target) | |
val gson = GsonBuilder().setPrettyPrinting().create() | |
val json: String = gson.toJson(this) | |
//Implement other targets | |
when(logTarget) { | |
LogTarget.TERMINAL -> println(json) | |
} | |
} | |
} | |
//Clean domain flow | |
fun main() { | |
val account = Account(1) | |
val personalInfo = PersonalInfo( | |
name = "Jefferson Didi Silva", | |
email = "[email protected]", | |
phone = "4002-8922", | |
cpf = "000.000.000-00" | |
) | |
val address = Address( | |
cep = "24466-970", | |
uf = "RJ", | |
city = "São Gonçalo", | |
street = "Rod. Niterói - Manilha", | |
district = "Boa Vista", | |
number = "100" | |
) | |
account add personalInfo | |
account add address | |
account logTo Terminal | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment