-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathRequest.kt
107 lines (92 loc) · 3.43 KB
/
Request.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.kord.rest.request
import dev.kord.rest.NamedFile
import dev.kord.rest.route.Route
import io.ktor.client.request.forms.*
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.util.*
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.json.Json
public sealed class Request<B : Any, R>(
public val baseUrl: String = Route.baseUrl
) {
public abstract val route: Route<R>
public abstract val routeParams: Map<Route.Key, String>
public abstract val headers: StringValues
public abstract val parameters: StringValues
public abstract val body: RequestBody<B>?
public abstract val files: List<NamedFile>?
public val path: String
get() {
var path = route.path
routeParams.forEach { (k, v) -> path = path.replaceFirst(k.identifier, v.encodeURLQueryComponent()) }
return path
}
}
public val Request<*, *>.identifier: RequestIdentifier
get() = when { //The major identifier is always the 'biggest' entity.
Route.GuildId in routeParams -> RequestIdentifier.MajorParamIdentifier(
route,
routeParams.getValue(Route.GuildId)
)
Route.ChannelId in routeParams -> RequestIdentifier.MajorParamIdentifier(
route,
routeParams.getValue(Route.ChannelId)
)
Route.WebhookId in routeParams -> RequestIdentifier.MajorParamIdentifier(
route,
routeParams.getValue(Route.WebhookId)
)
else -> RequestIdentifier.RouteIdentifier(route)
}
/**
* A ['per-route'](https://discord.com/developers/docs/topics/rate-limits) identifier for rate limiting purposes.
*/
public sealed class RequestIdentifier {
/**
* An identifier that does not contain any major parameters.
*/
public data class RouteIdentifier(val route: Route<*>) : RequestIdentifier()
/**
* An identifier with a major parameter.
*/
public data class MajorParamIdentifier(val route: Route<*>, val param: String) : RequestIdentifier()
}
public data class RequestBody<T>(val strategy: SerializationStrategy<T>, val body: T) where T : Any
public class JsonRequest<B : Any, R>(
override val route: Route<R>,
override val routeParams: Map<Route.Key, String>,
override val parameters: StringValues,
override val headers: StringValues,
override val body: RequestBody<B>?,
baseUrl: String = Route.baseUrl
) : Request<B, R>(baseUrl) {
override val files: List<NamedFile>? = null
}
public class MultipartRequest<B : Any, R>(
override val route: Route<R>,
override val routeParams: Map<Route.Key, String>,
override val parameters: StringValues,
override val headers: StringValues,
override val body: RequestBody<B>?,
override val files: List<NamedFile> = emptyList(),
baseUrl: String = Route.baseUrl
) : Request<B, R>(baseUrl) {
public val data: List<PartData> = formData {
body?.let {
append("payload_json", Json.encodeToString(it.strategy, it.body))
}
try {
files.forEachIndexed { index, pair ->
val (name, inputStream) = pair
append(
"file$index",
inputStream.readBytes(),
Headers.build { append(HttpHeaders.ContentDisposition, "filename=$name") }
)
}
} finally {
files.forEach { it.inputStream.close() }
}
}
}