@@ -10,21 +10,38 @@ import kotlin.reflect.full.hasAnnotation
1010import kotlin.reflect.full.memberProperties
1111import kotlin.reflect.full.superclasses
1212
13+ /* *
14+ * An HTTP query
15+ */
1316interface Query {
1417
1518 companion object {
1619
20+ /* *
21+ * Try to find the SerialName of a key, looping over superclasses
22+ */
1723 internal fun key (property : KProperty1 <Query , * >, kClass : KClass <* >) =
24+ // if the property has a custom SerialName get it
1825 property.findAnnotation<SerialName >()?.value
26+ // else, loop over all superclasses, until a name is found
1927 ? : kClass.superclasses.firstNotNullOfOrNull { superClass ->
2028 superClass.memberProperties
29+ // if a superclass has the property we're looking for
2130 .firstOrNull { it.name == property.name }
31+ // if the property has a custom SerialName get it
2232 ?.findAnnotation<SerialName >()?.value
23- } ? : property.name
33+ } ? : property.name // default to its name
2434
35+ /* *
36+ * Get the key name from a reified type
37+ */
2538 internal inline fun <reified T > key (property : KProperty1 <Query , * >) =
2639 key(property, T ::class )
2740
41+ /* *
42+ * Stringify a value (arrays are ',' joined, enums are looked up for
43+ * [SerialName]s; nulls are only filtered out from arrays)
44+ */
2845 @OptIn(InternalSerializationApi ::class , ExperimentalSerializationApi ::class )
2946 internal fun value (any : Any? ): String? =
3047 when (any) {
@@ -42,12 +59,21 @@ interface Query {
4259
4360 }
4461
62+ /* *
63+ * Useful to convert, for example, spaces to "%20"
64+ */
4565 private fun urlEncode (text : String ) =
4666 URLEncoder .encode(text, " utf-8" )
4767
68+ /* *
69+ * Calls the value companion method with `this` values
70+ */
4871 private fun value (property : KProperty1 <Query , * >) =
4972 Companion .value(property.get(this ))
5073
74+ /* *
75+ * Get all non-Transient properties
76+ */
5177 private val memberProperties
5278 get() =
5379 javaClass.kotlin.memberProperties
@@ -62,12 +88,21 @@ interface Query {
6288 memberProperties
6389 .mapNotNull { value(it)?.let { v -> key(it, javaClass.kotlin) to v } }
6490
91+ /* *
92+ * Like `.toList().toMap()`
93+ */
6594 fun toMap () =
6695 toList().toMap()
6796
97+ /* *
98+ * URL encode the query as `?key0=value0&key1=value1&...keyN=valueN` format
99+ */
68100 fun asString () =
69101 urlEncode(toList().joinToString(" &" , " ?" ) { (k, v) -> " $k =$v " })
70102
103+ /* *
104+ * Replace the context [URL] query with this one
105+ */
71106 fun toURL (context : URL ) =
72107 URL (context, " ${context.path}${asString()} " )
73108
0 commit comments