1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
package at.hannibal2.skyhanni.events
import at.hannibal2.skyhanni.config.migration.LoadResult
import at.hannibal2.skyhanni.config.migration.MigratingConfigLoader
import at.hannibal2.skyhanni.config.migration.ResolutionPath
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import java.lang.reflect.Field
import java.lang.reflect.Type
import kotlin.reflect.KProperty1
data class ConfigMigrationEvent(
val loader: MigratingConfigLoader,
val resolutionPath: ResolutionPath,
val objectHierarchy: List<JsonElement?>,
val type: Type,
var value: LoadResult<*>
) : LorenzEvent() {
val property = (resolutionPath as? ResolutionPath.FieldChild)?.field
fun use(value: Any?) {
this.value = LoadResult.Instance(value)
}
fun isFailing(): Boolean {
return value is LoadResult.Failure || value is LoadResult.Invalid
}
fun useDefault() {
this.value = LoadResult.UseDefault
}
data class MigrateContext(val hierarchy: List<JsonElement?>) {
fun parent(n: Int = 1): MigrateContext = MigrateContext(hierarchy.dropLast(n))
fun child(name: String) = MigrateContext(hierarchy + (hierarchy.last() as? JsonObject)?.get(name))
fun root(): MigrateContext = MigrateContext(hierarchy.take(1))
}
inline fun <reified T, V> migrate(prop: KProperty1<T, V>, noinline block: MigrateContext.() -> MigrateContext) {
if (prop.name != property?.name) return
val field = try {
T::class.java.getDeclaredField(prop.name)
} catch (e: NoSuchFieldException) {
return
}
migrate(field, block)
}
inline fun <reified T, V> migrate(
prop: KProperty1<T, V>,
noinline block: MigrateContext.() -> MigrateContext,
oldType: Type,
noinline mapper: (Any?) -> T?
) {
if (prop.name != property?.name) return
val field = try {
T::class.java.getDeclaredField(prop.name)
} catch (e: NoSuchFieldException) {
return
}
migrate(field, block, oldType, mapper)
}
fun migrate(prop: Field, block: MigrateContext.() -> MigrateContext) = migrate(prop, block, type) { it }
fun migrate(prop: Field, block: MigrateContext.() -> MigrateContext, oldType: Type, mapper: (Any?) -> Any?) {
if (prop != property) return
this.value =
loader.loadElement(resolutionPath, MigrateContext(objectHierarchy).let(block).hierarchy, oldType)
.map(mapper)
}
}
|