Best Fuel code snippet using com.github.kittinunf.fuel.private.deserialize
Deserializable.kt
Source:Deserializable.kt
1package com.github.kittinunf.fuel.core2import com.github.kittinunf.fuel.Fuel3import com.github.kittinunf.fuel.core.deserializers.EmptyDeserializer4import com.github.kittinunf.fuel.core.requests.CancellableRequest5import com.github.kittinunf.fuel.core.requests.DefaultBody6import com.github.kittinunf.fuel.core.requests.RequestTaskCallbacks7import com.github.kittinunf.fuel.core.requests.suspendable8import com.github.kittinunf.fuel.core.requests.toTask9import com.github.kittinunf.result.Result10import com.github.kittinunf.result.getOrElse11import com.github.kittinunf.result.map12import com.github.kittinunf.result.mapError13import java.io.InputStream14import java.io.Reader15import kotlin.jvm.Throws16/**17 * Generic interface for [Response] deserialization.18 *19 * @note you are responsible of using the [Response] [Body] [InputStream] and closing it when you're done. Failing to do20 * so can result in hanging connections if used in conjunction with [com.github.kittinunf.fuel.toolbox.HttpClient].21 *22 * @see ResponseDeserializable23 */24interface Deserializable<out T : Any> {25 /**26 * Deserialize [response] into [T]27 *28 * @param response [Response] the incoming response29 * @return [T] the instance of [T]30 */31 fun deserialize(response: Response): T32}33interface ResponseDeserializable<out T : Any> : Deserializable<T> {34 override fun deserialize(response: Response): T {35 response.body.toStream().use { stream ->36 return deserialize(stream)37 ?: deserialize(stream.reader())38 ?: reserialize(response, stream).let {39 deserialize(response.data)40 ?: deserialize(String(response.data))41 ?: throw FuelError.wrap(IllegalStateException(42 "One of deserialize(ByteArray) or deserialize(InputStream) or deserialize(Reader) or " +43 "deserialize(String) must be implemented"44 ))45 }46 }47 }48 private fun reserialize(response: Response, stream: InputStream): Response {49 val length = response.body.length50 response.body = DefaultBody.from({ stream }, length?.let { l -> { l } })51 return response52 }53 /**54 * Deserialize into [T] from an [InputStream]55 *56 * @param inputStream [InputStream] source bytes57 * @return [T] deserialized instance of [T] or null when not applied58 */59 fun deserialize(inputStream: InputStream): T? = null60 /**61 * Deserialize into [T] from a [Reader]62 *63 * @param reader [Reader] source bytes64 * @return [T] deserialized instance of [T] or null when not applied65 */66 fun deserialize(reader: Reader): T? = null67 /**68 * Deserialize into [T] from a [ByteArray]69 *70 * @note it is more efficient to implement the [InputStream] variant.71 *72 * @param bytes [ByteArray] source bytes73 * @return [T] deserialized instance of [T] or null when not applied74 */75 fun deserialize(bytes: ByteArray): T? = null76 /**77 * Deserialize into [T] from a [String]78 *79 * @note it is more efficient to implement the [Reader] variant.80 *81 * @param content [String] source bytes82 * @return [T] deserialized instance of [T] or null when not applied83 */84 fun deserialize(content: String): T? = null85}86/**87 * Deserialize the [Response] to the [this] into a [T] using [U]88 *89 * @see ResponseResultHandler90 *91 * @param deserializable [U] the instance that performs deserialization92 * @param handler [ResponseResultHandler<T>] handler that has a [Result]93 * @return [CancellableRequest] the request that can be cancelled94 */95fun <T : Any, U : Deserializable<T>> Request.response(deserializable: U, handler: ResponseResultHandler<T>): CancellableRequest =96 response(deserializable,97 { request, response, value -> handler(request, response, Result.Success(value)) },98 { request, response, error -> handler(request, response, Result.Failure(error)) }99 )100/**101 * Deserialize the [Response] to the [this] into a [T] using [U]102 *103 * @see ResultHandler104 *105 * @param deserializable [U] the instance that performs deserialization106 * @param handler [ResultHandler<T>] handler that has a [Result]107 * @return [CancellableRequest] the request that can be cancelled108 */109fun <T : Any, U : Deserializable<T>> Request.response(deserializable: U, handler: ResultHandler<T>): CancellableRequest =110 response(deserializable,111 { _, _, value -> handler(Result.Success(value)) },112 { _, _, error -> handler(Result.Failure(error)) }113 )114/**115 * Deserialize the [Response] to the [this] into a [T] using [U]116 *117 * @see ResponseHandler118 *119 * @param deserializable [U] the instance that performs deserialization120 * @param handler [ResponseHandler<T>] handler that has dedicated paths for success and failure121 * @return [CancellableRequest] the request that can be cancelled122 */123fun <T : Any, U : Deserializable<T>> Request.response(deserializable: U, handler: ResponseHandler<T>): CancellableRequest =124 response(deserializable,125 { request, response, value -> handler.success(request, response, value) },126 { request, response, error -> handler.failure(request, response, error) }127 )128/**129 * Deserialize the [Response] to the [this] into a [T] using [U]130 *131 * @see Handler132 *133 * @param deserializable [U] the instance that performs deserialization134 * @param handler [Handler<T>] handler that has dedicated paths for success and failure135 * @return [CancellableRequest] the request that can be cancelled136 */137fun <T : Any, U : Deserializable<T>> Request.response(deserializable: U, handler: Handler<T>): CancellableRequest =138 response(deserializable,139 { _, _, value -> handler.success(value) },140 { _, _, error -> handler.failure(error) }141 )142/**143 * Deserialize the [Response] to the [this] into a [T] using [U]144 *145 * @note not async, use the variations with a handler instead.146 *147 * @throws Exception if there is an internal library error, not related to Network or Deserialization148 *149 * @param deserializable [U] the instance that performs deserialization150 * @return [ResponseResultOf<T>] the response result of151 */152fun <T : Any, U : Deserializable<T>> Request.response(deserializable: U): ResponseResultOf<T> {153 // First execute the network request and catch any issues154 val rawResponse = runCatching { toTask().call() }155 .onFailure { error ->156 FuelError.wrap(error, Response.error(url)).also {157 return Triple(this, it.response, Result.error(it))158 }159 }160 .getOrThrow()161 // By this time it should have a response, but deserialization might fail162 return runCatching { Triple(this, rawResponse, Result.Success(deserializable.deserialize(rawResponse))) }163 .recover { error -> Triple(this, rawResponse, Result.Failure(FuelError.wrap(error, rawResponse))) }164 .getOrThrow()165}166/**167 * Ignore the response result168 *169 * Use this method to avoid huge memory allocation when using [com.github.kittinunf.fuel.core.requests.download]170 * to a large download and without using the result [ByteArray]171 *172 * @see [com.github.kittinunf.fuel.core.Request.response]173 *174 * @note not async, use the variations with a handler instead.175 *176 * @throws Exception if there is an internal library error, not related to Network177 */178fun Request.responseUnit(): ResponseResultOf<Unit> = response(EmptyDeserializer)179private fun <T : Any, U : Deserializable<T>> Request.response(180 deserializable: U,181 success: (Request, Response, T) -> Unit,182 failure: (Request, Response, FuelError) -> Unit183): CancellableRequest {184 val asyncRequest = RequestTaskCallbacks(185 request = this,186 onSuccess = { response ->187 // The network succeeded but deserialization might fail188 val deliverable = Result.of<T, Exception> { deserializable.deserialize(response) }189 executionOptions.callback {190 deliverable.fold(191 { success(this, response, it) },192 { failure(this, response, FuelError.wrap(it, response).also { error ->193 Fuel.trace { "[Deserializable] unfold failure: \n\r$error" } })194 }195 )196 }197 },198 onFailure = { error, response ->199 executionOptions.callback {200 failure(this, response, error.also { error ->201 Fuel.trace { "[Deserializable] callback failure: \n\r$error" }202 })203 }204 }205 )206 return CancellableRequest.enableFor(this, future = executionOptions.submit(asyncRequest))207}208/**209 * Await [T] or throws [FuelError]210 * @return [T] the [T]211 */212@Throws(FuelError::class)213suspend fun <T : Any, U : Deserializable<T>> Request.await(deserializable: U): T {214 val response = suspendable().await()215 return runCatching { deserializable.deserialize(response) }216 .onFailure { throw FuelError.wrap(it, response) }217 .getOrThrow()218}219/**220 * Await the task or throws [FuelError] in current coroutine context.221 *222 * Use this method to avoid huge memory allocation when using [com.github.kittinunf.fuel.core.requests.download]223 * to a large file without using response result224 *225 * To run method in different coroutine context, use `com.github.kittinunf.fuel.coroutines.awaitUnit` in `fuel-coroutines` module226 */227@Throws(FuelError::class)228suspend fun Request.awaitUnit(): Unit = await(EmptyDeserializer)229/**230 * Await [T] or [FuelError]231 * @return [ResponseOf<T>] the [Result] of [T]232 */233@Throws(FuelError::class)234suspend fun <T : Any, U : Deserializable<T>> Request.awaitResponse(deserializable: U): ResponseOf<T> {235 val response = suspendable().await()236 return runCatching { Triple(this, response, deserializable.deserialize(response)) }237 .onFailure { throw FuelError.wrap(it, response) }238 .getOrThrow()239}240/**241 * Await [T] or [FuelError]242 * @return [Result<T>] the [Result] of [T]243 */244suspend fun <T : Any, U : Deserializable<T>> Request.awaitResult(deserializable: U): Result<T, FuelError> {245 val initialResult = suspendable().awaitResult()246 return serializeFor(initialResult, deserializable).map { (_, t) -> t }247}248/**249 * Await [T] or [FuelError]250 * @return [ResponseResultOf<T>] the [ResponseResultOf] of [T]251 */252suspend fun <T : Any, U : Deserializable<T>> Request.awaitResponseResult(deserializable: U): ResponseResultOf<T> {253 val initialResult = suspendable().awaitResult()254 return serializeFor(initialResult, deserializable).let {255 Triple(this,256 it.fold({ (response, _) -> response }, { error -> error.response }),257 it.map { (_, t) -> t }258 )259 }260}261private fun <T : Any, U : Deserializable<T>> serializeFor(result: Result<Response, FuelError>, deserializable: U) =262 result.map { (it to deserializable.deserialize(it)) }263 .mapError <Pair<Response, T>, Exception, FuelError> {264 FuelError.wrap(it, result.getOrElse { Response.error() })265 }...
SpotifyClient.kt
Source:SpotifyClient.kt
...41 "redirect_uri" to redirectUrl,42 "client_id" to clientId,43 "client_secret" to clientSecret44 ))45 .deserialize()46 }47 internal suspend fun refreshToken(refreshToken: RefreshToken): Tokens {48 return Fuel.post("$accountsUrl/api/token",49 listOf(50 "grant_type" to "refresh_token",51 "refresh_token" to refreshToken52 ))53 .header("Authorization" to authString)54 .deserialize()55 }56 internal suspend fun getUserId(accessToken: AccessToken): SpotifyUserId {57 return get("$apiUrl/v1/me", accessToken)58 .deserialize<User>()59 .id60 }61 internal suspend fun getPlaylists(accessToken: AccessToken): List<Playlist> {62 return get("$apiUrl/v1/me/playlists", accessToken)63 .deserialize<PlaylistsResponse>()64 .items65 }66 internal suspend fun findArtist(accessToken: AccessToken, name: ArtistName): List<Artist> {67 return Fuel.get("$apiUrl/v1/search",68 listOf(69 "q" to name,70 "type" to "artist"71 ))72 .header("Accept" to "application/json")73 .addHeaders(accessToken)74 .deserialize<FindArtistResponse>()75 .artists.items76 }77 internal suspend fun getArtist(accessToken: AccessToken, artistId: ArtistId): Artist? {78 return Fuel.get("$apiUrl/v1/artists/$artistId")79 .header("Accept" to "application/json")80 .addHeaders(accessToken)81 .deserialize() //todo proper exception handling and nullability82 }83 internal suspend fun getAlbums(accessToken: AccessToken, artistId: ArtistId): List<Album> {84 // todo don't hardcode market, figure out users market85 return get("$apiUrl/v1/artists/$artistId/albums?include_groups=album,single&market=SE", accessToken)86 .deserialize<GetAlbumsResponse>()87 .items88 }89 internal suspend fun getTracks(accessToken: AccessToken, album: AlbumId): List<Track> {90 return get("$apiUrl/v1/albums/$album/tracks", accessToken)91 .deserialize<GetTracksFromAlbumResponse>()92 .items93 }94 internal suspend fun createPlaylist(95 accessToken: AccessToken,96 name: PlaylistName,97 description: String,98 public: Boolean99 ): Playlist {100 return post("$apiUrl/v1/me/playlists", accessToken)101 .body("""102 {103 "name":"$name",104 "description":"$description",105 "public":$public106 }107 """.trimIndent())108 .deserialize()109 }110 internal suspend fun getTracks(111 accessToken: AccessToken,112 playlistId: SpotifyPlaylistId113 ): List<Track> {114 return get("$apiUrl/v1/playlists/$playlistId/tracks", accessToken)115 .deserialize<GetTracksFromPlaylistResponse>()116 .items.map { it.track }117 }118 internal suspend fun addTracks(119 accessToken: AccessToken,120 playlist: SpotifyPlaylistId,121 tracks: List<TrackUri>122 ): SnapshotId {123 val request = AddTracksToPlaylistRequest(tracks)124 val json = mapper.writeValueAsString(request)125 return put("$apiUrl/v1/playlists/$playlist/tracks", accessToken)126 .body(json)127 .deserialize<AddTracksToPlaylistRespose>()128 .snapshot_id129 }130 private fun get(path: String, accessToken: AccessToken) = Fuel.get(path).addHeaders(accessToken)131 private fun post(path: String, accessToken: AccessToken) = Fuel.post(path).addHeaders(accessToken)132 private fun put(path: String, accessToken: AccessToken) = Fuel.put(path).addHeaders(accessToken)133 private fun Request.addHeaders(accessToken: AccessToken) = this.header(mapOf(134 "Content-Type" to "application/json",135 "Authorization" to "Bearer $accessToken"136 ))137 private suspend inline fun <reified T : Any> Request.deserialize(): T {138 val (_, _, result) = this.awaitStringResponseResult()139 when (result) {140 is Result.Failure -> {141 val ex = result.getException()142 if (result.error.response.statusCode == 429) {143 logger.warn("Rate limit exceeded")144 val retryAfter = result.error.response.headers["Retry-After"].firstOrNull()145 if (retryAfter == null) {146 logger.error("Missing retry-after header", ex)147 throw ex148 }149 throw RateLimitExceededException(retryAfter.toLong())150 }151 logger.error("Call failed: ${result.error.response}", ex)152 throw ex153 }154 is Result.Success -> {155 val data = result.get()156 val playListsResponse: T157 try {158 playListsResponse = mapper.readValue(data)159 return playListsResponse160 } catch (e: Exception) {161 logger.info("Unable to deserialize {}", data, e)162 throw kotlin.RuntimeException("Unable to deserialize $data: ${e.message}")163 }164 }165 }166 }167}...
FuelWebService.kt
Source:FuelWebService.kt
...63 Logger.error("${fuelError.response.statusCode} ${fuelError.response.url}", fuelError.exception)64 failure?.invoke(request, response, fuelError.exception)65 })66 }67 inline fun <reified T: Any> deserialize(content: String): T? =68 Deserializer(gson, T::class).deserialize(content)69 inner class Deserializer<T: Any>(private val gson: Gson, private val klass: KClass<T>): ResponseDeserializable<T> {70 override fun deserialize(content: String): T? {71 try {72 return gson.fromJson(content, klass.java)73 } catch (e: JsonSyntaxException) {74 Logger.wtf(e)75 return null76 }77 }78 }79}...
HttpPromenaTransformer.kt
Source:HttpPromenaTransformer.kt
...24 *25 * There is no time limit of the request. It should be completed by Promena.26 *27 * If the response status is:28 * - [HTTP_OK] - deserialize the body to [PerformedTransformationDescriptor]29 * - [HTTP_INTERNAL_ERROR] - deserialize the body to the class from [SERIALIZATION_CLASS] header - it will be a subclass of [Throwable]30 */31 suspend fun execute(transformationDescriptor: TransformationDescriptor, httpAddress: String): PerformedTransformationDescriptor =32 try {33 Fuel.post("http://$httpAddress/transform")34 .header(CONTENT_TYPE, APPLICATION_OCTET_STREAM.mimeType)35 .timeout(Int.MAX_VALUE)36 .timeoutRead(Int.MAX_VALUE)37 .body(serializationService.serialize(transformationDescriptor))38 .awaitByteArrayResponse()39 .let { (_, response, byteArray) -> handleTransformationResult(response, byteArray) }40 } catch (e: FuelError) {41 handleTransformationResult(e.response, e.errorData, e)42 }43 private fun handleTransformationResult(response: Response, bytes: ByteArray, cause: Throwable? = null): PerformedTransformationDescriptor =44 when (response.statusCode) {45 HTTP_OK ->46 serializationService.deserialize(bytes, getClazz())47 HTTP_INTERNAL_ERROR ->48 throw serializationService.deserialize(bytes, response.headers.getSerializationClass())49 else ->50 throw HttpException(response.statusCode, String(bytes), cause)51 }52 private inline fun <reified T : Any> getClazz(): Class<T> =53 T::class.java54 @Suppress("UNCHECKED_CAST")55 private fun <T> Headers.getSerializationClass(): Class<T> {56 if (!containsKey(SERIALIZATION_CLASS)) {57 throw NoSuchElementException("Headers don't contain <$SERIALIZATION_CLASS> entry. Unknown error occurred")58 }59 return try {60 Class.forName(this[SERIALIZATION_CLASS].first()) as Class<T>61 } catch (e: ClassNotFoundException) {62 throw IllegalArgumentException("Class indicated in <$SERIALIZATION_CLASS> header isn't available", e)...
ApiWrapper.kt
Source:ApiWrapper.kt
...39 post.file_url.httpDownload().fileDestination { _, _ ->40 destination41 }.awaitResult(NoopDeserializer)42 object PostDeserializer : ResponseDeserializable<List<Post>> {43 override fun deserialize(content: String): List<Post> = Gson().fromJson(content, Array<Post>::class.java).toList()44 }45 object TagDeserializer : ResponseDeserializable<List<Tag>> {46 override fun deserialize(content: String): List<Tag> = Gson().fromJson(content, Array<Tag>::class.java).toList()47 }48 object NoopDeserializer : ResponseDeserializable<Unit> {49 override fun deserialize(content: String): Unit = Unit50 }51}...
RemoteRepo.kt
Source:RemoteRepo.kt
...43 url: String,44 params: Parameters? = null45 ): Either<Throwable, T> = Either.catch {46 val response = url.httpGet(params).awaitStringResult().catchable()47 response.deserialize<T>()48 }.flatten()49 private suspend inline fun <reified T : Any> String.deserialize(): Either<Throwable, T> =50 Either.catch {51 Json.decodeFromString(deserializer = T::class.serializer(), string = this)52 }.also {53 if (it.isLeft()) {54 Timber.e("Error deserializing to ${T::class.java}: $this")55 }56 }57 private fun com.github.kittinunf.result.Result<String, FuelError>.catchable(): String =58 fold(59 { it },60 {61 Timber.e("Error fetching url: $it")62 throw it63 }64 )65}...
FuelPlanetDatasource.kt
Source:FuelPlanetDatasource.kt
...17 is Result.Success -> {18 val planets = mutableListOf<Planet>()19 val planetsJson = result.value.array()20 for(i in 0 until planetsJson.length()) {21 planets.add(deserializePlanet(planetsJson.getJSONObject(i)))22 }23 return@withContext planets24 }25 // 400 codes26 is Result.Failure -> {27 throw result.error.exception28 }29 }30 }31 }32 private fun deserializePlanet(planetJson: JSONObject) : Planet {33 val name = planetJson.getString("name")34 val image = planetJson.getString("icon")35 val temperature = planetJson.getDouble("temperature")36 return Planet(name, image, temperature)37 }38}...
PicsumClient.kt
Source:PicsumClient.kt
1package com.priambudi19.pagingcompose.data.network2import com.github.kittinunf.fuel.Fuel3import com.github.kittinunf.fuel.core.FuelError4import com.github.kittinunf.fuel.core.Request5import com.github.kittinunf.fuel.core.RequestFactory6import com.github.kittinunf.result.Result7import com.priambudi19.pagingcompose.data.model.PicsumPhotos8class PicsumClient : PicsumService {9 private fun request(api: RequestFactory.RequestConvertible): Request {10 return Fuel.request(api).timeout(30000)11 }12 override fun getListPhotos(page: Int): Result<List<PicsumPhotos>, FuelError> {13 val (_, _, result) = request(PicsumApi.ListPhoto(page)).responseObject(PicsumPhotos.DeserializeList)14 return result15 }16 override fun getPhotos(id: Int): Result<PicsumPhotos, FuelError> {17 val (_, _, result) = request(PicsumApi.Photo(id)).responseObject(PicsumPhotos.Deserialize)18 return result19 }20}...
deserialize
Using AI Code Generation
1import com.github.kittinunf.fuel.core.ResponseDeserializable2import com.google.gson.Gson3class Deserializer<T>(private val type: Class<T>) : ResponseDeserializable<T> {4override fun deserialize(content: String): T? {5return Gson().fromJson(content, type)6}7}8val (data, error) = result9data?.let {10println(it.name)11}12}13}14data class User(val login: String, val id: Int, val name: String, val blog
deserialize
Using AI Code Generation
1private class JsonDeserializer {2 companion object {3 fun deserialize(response: Response, type: Type) : Any {4 return Gson().fromJson(response.data.toString(Charsets.UTF_8), type)5 }6 }7}8private class JsonDeserializer {9 companion object {10 fun deserialize(response: Response, type: Type) : Any {11 return Gson().fromJson(response.data.toString(Charsets.UTF_8), type)12 }13 }14}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!