-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathViewModel.kt
More file actions
112 lines (97 loc) · 3.27 KB
/
ViewModel.kt
File metadata and controls
112 lines (97 loc) · 3.27 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package com.dmm.eikaiwa.viewmodels
import com.dmm.eikaiwa.serialization.json.JsonParser
import com.dmm.eikaiwa.serialization.json.copy
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.modules.SerializersModule
import kotlin.uuid.Uuid
interface ViewModel {
companion object
}
interface Identifiable {
val id: Uuid
}
@Serializable
open class ViewModelRecord(override val id: Uuid = Uuid.random()) : ViewModel, Identifiable {
@Transient
var isNew: Boolean = true
@Suppress("UNCHECKED_CAST")
fun <T> notNew(): T = apply { isNew = false } as T
}
interface ViewModelMetadata: ViewModelVersions {
val typeName: String
val version: Int
val root: Boolean
get() = false
val properties: Map<String, ViewModelProperty>
get() = emptyMap()
override val nestedVersions: Map<String, Int>
get() {
val models = properties.values.filterIsInstance<HasModelVersions>()
val versions = models.fold<HasModelVersions, Map<String, Int>>(emptyMap()) { acc, it ->
acc + it.versions.nestedVersions
}
val selfVersion = mapOf(typeName to version)
return selfVersion + versions
}
}
interface ViewModelMeta : ViewModelVersions
interface ViewModelSupplementary : ViewModelVersions
interface ViewModelVersions {
val nestedVersions: Map<String, Int>
}
interface PartialMetadata<T> {
val event: String
val serializer: KSerializer<T>
}
fun <T: Identifiable> ViewModel.Companion.encode(serializer: KSerializer<T>, model: T): String {
val referenceCache = ViewModelReferenceCache()
return JsonViewModelEncoder(
JsonParser.copy(
serializersModule = SerializersModule {
contextual(
ViewModelContext::class,
ViewModelContextSerializer(referenceCache, listOf(model.id))
)
}
),
serializer,
model
).encode()
}
fun <T> ViewModel.Companion.decode(
modelSerializer: KSerializer<T>,
string: String
): T {
val referenceCache = ViewModelReferenceCache()
val decoder = JsonViewModelDecoder(string,
JsonParser.copy(
serializersModule = SerializersModule {
contextual(ViewModelContext::class, ViewModelContextSerializer(referenceCache, null))
}
)
)
return decoder.parse(modelSerializer).getOrThrow().first
}
fun <T> ViewModel.Companion.decodePartial(
modelSerializer: KSerializer<T>,
string: String
): T {
return JsonParser.decodeFromString(modelSerializer, string)
}
fun <T, Meta, Supplementary> ViewModel.Companion.decode(
modelSerializer: KSerializer<T>,
metaSerializer: KSerializer<Meta>,
supplementarySerializer: KSerializer<Supplementary>,
string: String
): ViewModelParseResult<T, Meta, Supplementary> {
val referenceCache = ViewModelReferenceCache()
return JsonViewModelDecoder(string,
JsonParser.copy(
serializersModule = SerializersModule {
contextual(ViewModelContext::class, ViewModelContextSerializer(referenceCache, null))
}
)
).parse(modelSerializer, metaSerializer, supplementarySerializer)
}