Skip to content

Instantly share code, notes, and snippets.

@AchrafAmil
Created January 23, 2021 22:14
Show Gist options
  • Save AchrafAmil/b3a9b073bb8a38e1369b9612a53377e4 to your computer and use it in GitHub Desktop.
Save AchrafAmil/b3a9b073bb8a38e1369b9612a53377e4 to your computer and use it in GitHub Desktop.
data class AA(
val a1: String,
val a2: BB,
val a3: Int,
)
data class BB(
val b1: CC,
val b2: Int,
)
data class CC(
val c1: String,
val c2: String
)
fun main() {
val foo = AA(
a1 = "A here",
a2 = BB(
b1 = CC(
c1 = "C here",
c2 = "Hello!"
),
b2 = 2
),
a3 = 1
)
val bar = foo.copy(a2 = foo.a2.copy(b1 = foo.a2.b1.copy(c2 = "Hello world!")))
val bar2 = foo.mutate { ::a2 }.then { ::b1 }.then { ::c2 }.replace("Hello world!")
println("foo=$foo")
println("bar=$bar")
println("bar=$bar2")
//val bar2 = foo.mutate { it.a2.b1.c2 }.with("Hello world!")
}
fun <T : Any, A : Any> T.mutate(fieldToMutate: T.() -> KProperty0<A>): Then<T, A> {
return Then(this, fieldToMutate.invoke(this))
}
class Then<T, A>(val origin: T, val acc: KProperty0<A>)
class Then2<T, A, B>(val origin: T, val acc: KProperty0<A>, val acc2: KProperty0<B>)
class Then3<T, A, B, C>(val origin: T, val acc: KProperty0<A>, val acc2: KProperty0<B>, val acc3: KProperty0<C>)
class Then4<T, A, B, C, D>(val origin: T, val acc: KProperty0<A>, val acc2: KProperty0<B>, val acc3: KProperty0<C>, val acc4: KProperty0<D>)
class Then5<T, A, B, C, D, E>(val origin: T, val acc: KProperty0<A>, val acc2: KProperty0<B>, val acc3: KProperty0<C>, val acc4: KProperty0<D>, val acc5: KProperty0<E>)
class Then6<T, A, B, C, D, E, F>(val origin: T, val acc: KProperty0<A>, val acc2: KProperty0<B>, val acc3: KProperty0<C>, val acc4: KProperty0<D>, val acc5: KProperty0<E>, val acc6: KProperty0<F>)
inline fun<reified T: Any, reified A: Any> Then<T, A>.replace(with: A): T {
val originCopy = T::class.memberFunctions.first { it.name == "copy" }
return originCopy.callBy(mapOf(
originCopy.instanceParameter!! to this.origin,
originCopy.parameters.first { it.name == acc.name } to with
)) as T
}
inline fun<reified T: Any, reified A: Any, reified B: Any> Then2<T, A, B>.replace(with: B): T {
val originCopy = T::class.memberFunctions.first { it.name == "copy" }
return originCopy.callBy(mapOf(
originCopy.instanceParameter!! to this.origin,
originCopy.parameters.first { it.name == acc.name } to acc.invoke().mutate { acc2 }.replace(with)
)) as T
}
inline fun<reified T: Any, reified A: Any, reified B: Any, reified C: Any> Then3<T, A, B, C>.replace(with: C): T {
val originCopy = T::class.memberFunctions.first { it.name == "copy" }
return originCopy.callBy(mapOf(
originCopy.instanceParameter!! to this.origin,
originCopy.parameters.first { it.name == acc.name } to acc.invoke().mutate { acc2 }.then { acc3 }.replace(with)
)) as T
}
inline fun<reified T: Any, reified A: Any, reified B: Any, reified C: Any, reified D: Any> Then4<T, A, B, C, D>.replace(with: D): T {
val originCopy = T::class.memberFunctions.first { it.name == "copy" }
return originCopy.callBy(mapOf(
originCopy.instanceParameter!! to this.origin,
originCopy.parameters.first { it.name == acc.name } to acc.invoke().mutate { acc2 }.then { acc3 }.then { acc4 }.replace(with)
)) as T
}
inline fun<reified T: Any, reified A: Any, reified B: Any, reified C: Any, reified D: Any, reified E: Any> Then5<T, A, B, C, D, E>.replace(with: E): T {
val originCopy = T::class.memberFunctions.first { it.name == "copy" }
return originCopy.callBy(mapOf(
originCopy.instanceParameter!! to this.origin,
originCopy.parameters.first { it.name == acc.name } to acc.invoke().mutate { acc2 }.then { acc3 }.then { acc4 }.then { acc5 }.replace(with)
)) as T
}
inline fun<reified T: Any, reified A: Any, reified B: Any, reified C: Any, reified D: Any, reified E: Any, reified F: Any> Then6<T, A, B, C, D, E, F>.replace(with: F): T {
val originCopy = T::class.memberFunctions.first { it.name == "copy" }
return originCopy.callBy(mapOf(
originCopy.instanceParameter!! to this.origin,
originCopy.parameters.first { it.name == acc.name } to acc.invoke().mutate { acc2 }.then { acc3 }.then { acc4 }.then { acc5 }.then { acc6 }.replace(with)
)) as T
}
fun <T : Any, N : Any, O : Any> Then<T, N>.then(fieldToMutate: N.() -> KProperty0<O>): Then2<T, N, O> {
return Then2(origin, acc, fieldToMutate.invoke(acc.invoke()))
}
fun <T : Any, N : Any, O : Any, P : Any> Then2<T, N, O>.then(fieldToMutate: O.() -> KProperty0<P>): Then3<T, N, O, P> {
return Then3(origin, acc, acc2, fieldToMutate.invoke(acc2.invoke()))
}
fun <T : Any, N : Any, O : Any, P : Any, Q: Any> Then3<T, N, O, P>.then(fieldToMutate: P.() -> KProperty0<Q>): Then4<T, N, O, P, Q> {
return Then4(origin, acc, acc2, acc3, fieldToMutate.invoke(acc3.invoke()))
}
fun <T : Any, N : Any, O : Any, P : Any, Q: Any, R: Any> Then4<T, N, O, P, Q>.then(fieldToMutate: Q.() -> KProperty0<R>): Then5<T, N, O, P, Q, R> {
return Then5(origin, acc, acc2, acc3, acc4, fieldToMutate.invoke(acc4.invoke()))
}
fun <T : Any, N : Any, O : Any, P : Any, Q: Any, R: Any, S: Any> Then5<T, N, O, P, Q, R>.then(fieldToMutate: R.() -> KProperty0<S>): Then6<T, N, O, P, Q, R, S> {
return Then6(origin, acc, acc2, acc3, acc4, acc5, fieldToMutate.invoke(acc5.invoke()))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment