@@ -14,27 +14,33 @@ import kotlin.reflect.KClass
14
14
import kotlinx.serialization.KSerializer
15
15
import kotlinx.serialization.builtins.MapSerializer
16
16
import kotlinx.serialization.builtins.serializer
17
- import kotlinx.serialization.decodeFromString
18
- import kotlinx.serialization.encodeToString
19
17
import kotlinx.serialization.json.Json
20
18
import kotlinx.serialization.json.JsonElement
21
19
import kotlinx.serialization.json.JsonObject
22
20
23
21
internal val nonstrictJson =
24
- Json {
25
- isLenient = true
26
- ignoreUnknownKeys = true
27
- allowSpecialFloatingPointValues = true
28
- useArrayPolymorphism = true
29
- }
22
+ Json {
23
+ isLenient = true
24
+ ignoreUnknownKeys = true
25
+ allowSpecialFloatingPointValues = true
26
+ useArrayPolymorphism = true
27
+ }
30
28
31
- internal inline fun <reified T : Any > String.toObjectNullable (serializer : KSerializer <T >, api : GenericSpotifyApi ? , json : Json ): T ? = try {
29
+ internal inline fun <reified T : Any > String.toObjectNullable (
30
+ serializer : KSerializer <T >,
31
+ api : GenericSpotifyApi ? ,
32
+ json : Json
33
+ ): T ? = try {
32
34
toObject(serializer, api, json)
33
35
} catch (e: Exception ) {
34
36
null
35
37
}
36
38
37
- internal inline fun <reified T : Any > String.toObject (serializer : KSerializer <T >, api : GenericSpotifyApi ? , json : Json ): T {
39
+ internal inline fun <reified T : Any > String.toObject (
40
+ serializer : KSerializer <T >,
41
+ api : GenericSpotifyApi ? ,
42
+ json : Json
43
+ ): T {
38
44
return this .parseJson {
39
45
val obj = json.decodeFromString(serializer, this )
40
46
api?.let {
@@ -46,7 +52,11 @@ internal inline fun <reified T : Any> String.toObject(serializer: KSerializer<T>
46
52
}
47
53
}
48
54
49
- internal inline fun <reified T > String.toList (serializer : KSerializer <List <T >>, api : GenericSpotifyApi ? , json : Json ): List <T > {
55
+ internal inline fun <reified T > String.toList (
56
+ serializer : KSerializer <List <T >>,
57
+ api : GenericSpotifyApi ? ,
58
+ json : Json
59
+ ): List <T > {
50
60
return this .parseJson {
51
61
json.decodeFromString(serializer, this ).apply {
52
62
if (api != null ) {
@@ -70,22 +80,23 @@ internal fun <T : Any> String.toPagingObject(
70
80
): NullablePagingObject <T > {
71
81
if (innerObjectName != null || (arbitraryInnerNameAllowed && ! skipInnerNameFirstIfPossible)) {
72
82
val jsonObjectRoot = (json.parseToJsonElement(this ) as JsonObject )
73
- val jsonElement = innerObjectName?.let { jsonObjectRoot[it] } ? : jsonObjectRoot.keys.firstOrNull()?.let { jsonObjectRoot[it] }
74
- ? : throw SpotifyException .ParseException (" Json element was null for class $tClazz (json $this )" )
83
+ val jsonElement =
84
+ innerObjectName?.let { jsonObjectRoot[it] } ? : jsonObjectRoot.keys.firstOrNull()?.let { jsonObjectRoot[it] }
85
+ ? : throw SpotifyException .ParseException (" Json element was null for class $tClazz (json $this )" )
75
86
val objectString = jsonElement.toString()
76
87
77
88
val map = objectString.parseJson {
78
- json.decodeFromString(NullablePagingObject .serializer(tSerializer),this )
89
+ json.decodeFromString(NullablePagingObject .serializer(tSerializer), this )
79
90
}
80
91
81
92
return map.apply {
82
- this .endpoint = endpoint
83
- this .itemClazz = tClazz
84
- this .items.map { obj ->
85
- if (obj is NeedsApi ) obj.api = endpoint.api
86
- if (obj is PagingObjectBase <* , * >) obj.endpoint = endpoint
87
- }
88
- }
93
+ this .endpoint = endpoint
94
+ this .itemClazz = tClazz
95
+ this .items.map { obj ->
96
+ if (obj is NeedsApi ) obj.api = endpoint.api
97
+ if (obj is PagingObjectBase <* , * >) obj.endpoint = endpoint
98
+ }
99
+ }
89
100
}
90
101
91
102
return try {
@@ -102,19 +113,23 @@ internal fun <T : Any> String.toPagingObject(
102
113
} catch (jde: SpotifyException .ParseException ) {
103
114
if (arbitraryInnerNameAllowed && jde.message?.contains(" unable to parse" , true ) == true ) {
104
115
toPagingObject(
105
- tClazz,
106
- tSerializer,
107
- innerObjectName,
108
- endpoint,
109
- json,
110
- arbitraryInnerNameAllowed = true ,
111
- skipInnerNameFirstIfPossible = false
116
+ tClazz,
117
+ tSerializer,
118
+ innerObjectName,
119
+ endpoint,
120
+ json,
121
+ arbitraryInnerNameAllowed = true ,
122
+ skipInnerNameFirstIfPossible = false
112
123
)
113
124
} else throw jde
114
125
}
115
126
}
116
127
117
- internal fun <T : Any > initPagingObject (tClazz : KClass <T >, pagingObject : PagingObjectBase <T , * >, endpoint : SpotifyEndpoint ) {
128
+ internal fun <T : Any > initPagingObject (
129
+ tClazz : KClass <T >,
130
+ pagingObject : PagingObjectBase <T , * >,
131
+ endpoint : SpotifyEndpoint
132
+ ) {
118
133
pagingObject.apply {
119
134
this .endpoint = endpoint
120
135
this .itemClazz = tClazz
@@ -132,7 +147,14 @@ internal inline fun <reified T : Any> String.toPagingObject(
132
147
json : Json ,
133
148
arbitraryInnerNameAllowed : Boolean = false,
134
149
skipInnerNameFirstIfPossible : Boolean = true
135
- ): PagingObject <T > = toNullablePagingObject(tSerializer, innerObjectName, endpoint, json, arbitraryInnerNameAllowed, skipInnerNameFirstIfPossible).toPagingObject()
150
+ ): PagingObject <T > = toNullablePagingObject(
151
+ tSerializer,
152
+ innerObjectName,
153
+ endpoint,
154
+ json,
155
+ arbitraryInnerNameAllowed,
156
+ skipInnerNameFirstIfPossible
157
+ ).toPagingObject()
136
158
137
159
internal inline fun <reified T : Any > String.toNullablePagingObject (
138
160
tSerializer : KSerializer <T >,
@@ -141,7 +163,15 @@ internal inline fun <reified T : Any> String.toNullablePagingObject(
141
163
json : Json ,
142
164
arbitraryInnerNameAllowed : Boolean = false,
143
165
skipInnerNameFirstIfPossible : Boolean = true
144
- ): NullablePagingObject <T > = toPagingObject(T ::class , tSerializer, innerObjectName, endpoint, json, arbitraryInnerNameAllowed, skipInnerNameFirstIfPossible)
166
+ ): NullablePagingObject <T > = toPagingObject(
167
+ T ::class ,
168
+ tSerializer,
169
+ innerObjectName,
170
+ endpoint,
171
+ json,
172
+ arbitraryInnerNameAllowed,
173
+ skipInnerNameFirstIfPossible
174
+ )
145
175
146
176
internal fun <T : Any > String.toCursorBasedPagingObject (
147
177
tClazz : KClass <T >,
@@ -158,25 +188,26 @@ internal fun <T : Any> String.toCursorBasedPagingObject(
158
188
json.decodeFromString(MapSerializer (t.first, t.second), this )
159
189
}
160
190
return (map[innerObjectName] ? : if (arbitraryInnerNameAllowed) map.keys.firstOrNull()?.let { map[it] }
161
- ? : error(" " ) else error(" " ))
162
- .apply { initPagingObject(tClazz, this , endpoint) }
191
+ ? : error(" " ) else error(" " ))
192
+ .apply { initPagingObject(tClazz, this , endpoint) }
163
193
}
164
194
return try {
165
- val pagingObject = this .parseJson { json.decodeFromString(CursorBasedPagingObject .serializer(tSerializer), this ) }
195
+ val pagingObject =
196
+ this .parseJson { json.decodeFromString(CursorBasedPagingObject .serializer(tSerializer), this ) }
166
197
167
198
initPagingObject(tClazz, pagingObject, endpoint)
168
199
169
200
pagingObject
170
201
} catch (jde: SpotifyException .ParseException ) {
171
202
if (! arbitraryInnerNameAllowed && jde.message?.contains(" unable to parse" , true ) == true ) {
172
203
toCursorBasedPagingObject(
173
- tClazz,
174
- tSerializer,
175
- innerObjectName,
176
- endpoint,
177
- json,
178
- arbitraryInnerNameAllowed = true ,
179
- skipInnerNameFirstIfPossible = false
204
+ tClazz,
205
+ tSerializer,
206
+ innerObjectName,
207
+ endpoint,
208
+ json,
209
+ arbitraryInnerNameAllowed = true ,
210
+ skipInnerNameFirstIfPossible = false
180
211
)
181
212
} else throw jde
182
213
}
@@ -190,7 +221,15 @@ internal inline fun <reified T : Any> String.toCursorBasedPagingObject(
190
221
arbitraryInnerNameAllowed : Boolean = false,
191
222
skipInnerNameFirstIfPossible : Boolean = true
192
223
): CursorBasedPagingObject <T > =
193
- toCursorBasedPagingObject(T ::class , tSerializer, innerObjectName, endpoint, json, arbitraryInnerNameAllowed, skipInnerNameFirstIfPossible)
224
+ toCursorBasedPagingObject(
225
+ T ::class ,
226
+ tSerializer,
227
+ innerObjectName,
228
+ endpoint,
229
+ json,
230
+ arbitraryInnerNameAllowed,
231
+ skipInnerNameFirstIfPossible
232
+ )
194
233
195
234
internal inline fun <reified T > String.toInnerObject (serializer : KSerializer <T >, innerName : String , json : Json ): T {
196
235
val map = this .parseJson {
@@ -200,7 +239,11 @@ internal inline fun <reified T> String.toInnerObject(serializer: KSerializer<T>,
200
239
return (map[innerName] ? : error(" Inner object with name $innerName doesn't exist in $map " ))
201
240
}
202
241
203
- internal inline fun <reified T > String.toInnerArray (serializer : KSerializer <List <T >>, innerName : String , json : Json ): List <T > {
242
+ internal inline fun <reified T > String.toInnerArray (
243
+ serializer : KSerializer <List <T >>,
244
+ innerName : String ,
245
+ json : Json
246
+ ): List <T > {
204
247
val map = this .parseJson {
205
248
val t = (String .serializer() to serializer)
206
249
json.decodeFromString(MapSerializer (t.first, t.second), this )
@@ -210,17 +253,20 @@ internal inline fun <reified T> String.toInnerArray(serializer: KSerializer<List
210
253
211
254
internal fun Map <String , JsonElement >.toJson () = JsonObject (this ).toString()
212
255
213
- internal fun <A , B > createMapSerializer (aSerializer : KSerializer <A >, bSerializer : KSerializer <B >): KSerializer <Map <A , B >> {
256
+ internal fun <A , B > createMapSerializer (
257
+ aSerializer : KSerializer <A >,
258
+ bSerializer : KSerializer <B >
259
+ ): KSerializer <Map <A , B >> {
214
260
val t = (aSerializer to bSerializer)
215
261
return MapSerializer (t.first, t.second)
216
262
}
217
263
218
264
internal fun <T > String.parseJson (producer : String .() -> T ): T =
219
- try {
220
- producer(this )
221
- } catch (e: Exception ) {
222
- throw SpotifyException .ParseException (
223
- " Unable to parse $this (${e.message} )" ,
224
- e
225
- )
226
- }
265
+ try {
266
+ producer(this )
267
+ } catch (e: Exception ) {
268
+ throw SpotifyException .ParseException (
269
+ " Unable to parse $this (${e.message} )" ,
270
+ e
271
+ )
272
+ }
0 commit comments