-
Notifications
You must be signed in to change notification settings - Fork 2
/
KtorReadKeyValuesRepoRoutes.kt
108 lines (96 loc) · 3.68 KB
/
KtorReadKeyValuesRepoRoutes.kt
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
package dev.inmo.micro_utils.repos.ktor.server.key.values
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
import dev.inmo.micro_utils.repos.ktor.common.*
import dev.inmo.micro_utils.repos.ktor.common.containsRoute
import dev.inmo.micro_utils.repos.ktor.common.countRoute
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import io.ktor.http.*
import io.ktor.server.application.call
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.get
import io.ktor.util.InternalAPI
import io.ktor.util.reflect.typeInfo
import kotlinx.serialization.*
@OptIn(InternalAPI::class)
inline fun <reified Key, reified Value> Route.configureReadKeyValuesRepoRoutes (
originalRepo: ReadKeyValuesRepo<Key, Value>,
noinline keyDeserializer: suspend (String) -> Key,
noinline valueDeserializer: suspend (String) -> Value
) {
val paginationWithValuesTypeInfo = typeInfo<PaginationResult<Value>>()
val paginationWithKeysTypeInfo = typeInfo<PaginationResult<Key>>()
get(getRoute) {
val key = keyDeserializer(
call.getQueryParameterOrSendError(keyParameterName) ?: return@get
)
val pagination = call.request.queryParameters.extractPagination
val reversed = call.getQueryParameter(reversedParameterName) ?.toBoolean() ?: false
call.respond(
originalRepo.get(key, pagination, reversed),
paginationWithValuesTypeInfo
)
}
get(keysRoute) {
val pagination = call.request.queryParameters.extractPagination
val reversed = call.getQueryParameter(reversedParameterName) ?.toBoolean() ?: false
val value = call.getQueryParameter(valueParameterName) ?.let {
valueDeserializer(it)
}
call.respond(
value ?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed),
paginationWithKeysTypeInfo
)
}
get(containsRoute) {
val key = keyDeserializer(
call.getQueryParameterOrSendError(keyParameterName) ?: return@get
)
val value = call.getQueryParameter(valueParameterName) ?.let {
valueDeserializer(it)
}
call.respond(
value ?.let { originalRepo.contains(key, value) } ?: originalRepo.contains(key)
)
}
get(countRoute) {
val id = call.getQueryParameter(keyParameterName) ?.let {
keyDeserializer(it)
}
call.respond(
id ?.let { originalRepo.count(it) } ?: originalRepo.count()
)
}
}
inline fun <reified Key, reified Value> Route.configureReadKeyValuesRepoRoutes(
originalRepo: ReadKeyValuesRepo<Key, Value>,
keySerializer: DeserializationStrategy<Key>,
valueSerializer: DeserializationStrategy<Value>,
serialFormat: StringFormat
) = configureReadKeyValuesRepoRoutes(
originalRepo,
{
serialFormat.decodeFromString(keySerializer, it.decodeURLQueryComponent())
},
{
serialFormat.decodeFromString(valueSerializer, it.decodeURLQueryComponent())
}
)
inline fun <reified Key, reified Value> Route.configureReadKeyValuesRepoRoutes(
originalRepo: ReadKeyValuesRepo<Key, Value>,
keySerializer: DeserializationStrategy<Key>,
valueSerializer: DeserializationStrategy<Value>,
serialFormat: BinaryFormat
) = configureReadKeyValuesRepoRoutes(
originalRepo,
{
serialFormat.decodeHex(keySerializer, it)
},
{
serialFormat.decodeHex(valueSerializer, it)
}
)