From ae6ccfb200cc020f780d0c16e9a86fb293c9e270 Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 27 Mar 2023 11:43:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/BookSourceController.kt | 5 ++-- .../app/api/controller/RssSourceController.kt | 9 ++++--- .../io/legado/app/data/entities/BookSource.kt | 27 ------------------- .../io/legado/app/data/entities/RssSource.kt | 20 ++++---------- .../app/data/entities/rule/BookInfoRule.kt | 9 ++++--- .../app/data/entities/rule/ContentRule.kt | 9 ++++--- .../app/data/entities/rule/ExploreRule.kt | 9 ++++--- .../app/data/entities/rule/ReviewRule.kt | 6 ++--- .../app/data/entities/rule/SearchRule.kt | 6 ++--- .../legado/app/data/entities/rule/TocRule.kt | 6 ++--- .../java/io/legado/app/help/DefaultData.kt | 2 +- .../ui/association/ImportBookSourceDialog.kt | 2 +- .../association/ImportBookSourceViewModel.kt | 17 ++++++------ .../ui/association/ImportRssSourceDialog.kt | 2 +- .../association/ImportRssSourceViewModel.kt | 6 ++--- .../source/edit/BookSourceEditViewModel.kt | 4 +-- .../rss/source/edit/RssSourceEditViewModel.kt | 9 +++---- .../io/legado/app/utils/GsonExtensions.kt | 14 ++++++++-- 18 files changed, 73 insertions(+), 89 deletions(-) diff --git a/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt b/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt index 1d6a9d345..f6742bc31 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt @@ -8,6 +8,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.help.config.SourceConfig import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonArray +import io.legado.app.utils.fromJsonObject object BookSourceController { @@ -23,7 +24,7 @@ object BookSourceController { fun saveSource(postData: String?): ReturnData { val returnData = ReturnData() postData ?: return returnData.setErrorMsg("数据不能为空") - val bookSource = BookSource.fromJson(postData).getOrNull() + val bookSource = GSON.fromJsonObject(postData).getOrNull() if (bookSource != null) { if (TextUtils.isEmpty(bookSource.bookSourceName) || TextUtils.isEmpty(bookSource.bookSourceUrl)) { returnData.setErrorMsg("源名称和URL不能为空") @@ -40,7 +41,7 @@ object BookSourceController { fun saveSources(postData: String?): ReturnData { postData ?: return ReturnData().setErrorMsg("数据为空") val okSources = arrayListOf() - val bookSources = BookSource.fromJsonArray(postData).getOrNull() + val bookSources = GSON.fromJsonArray(postData).getOrNull() if (bookSources.isNullOrEmpty()) { return ReturnData().setErrorMsg("转换源失败") } diff --git a/app/src/main/java/io/legado/app/api/controller/RssSourceController.kt b/app/src/main/java/io/legado/app/api/controller/RssSourceController.kt index 6df9c5b28..b60b8ae0f 100644 --- a/app/src/main/java/io/legado/app/api/controller/RssSourceController.kt +++ b/app/src/main/java/io/legado/app/api/controller/RssSourceController.kt @@ -5,6 +5,9 @@ import android.text.TextUtils import io.legado.app.api.ReturnData import io.legado.app.data.appDb import io.legado.app.data.entities.RssSource +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonArray +import io.legado.app.utils.fromJsonObject object RssSourceController { @@ -20,7 +23,7 @@ object RssSourceController { fun saveSource(postData: String?): ReturnData { val returnData = ReturnData() postData ?: return returnData.setErrorMsg("数据不能为空") - RssSource.fromJson(postData).onFailure { + GSON.fromJsonObject(postData).onFailure { returnData.setErrorMsg("转换源失败${it.localizedMessage}") }.onSuccess { source -> if (TextUtils.isEmpty(source.sourceName) || TextUtils.isEmpty(source.sourceUrl)) { @@ -36,7 +39,7 @@ object RssSourceController { fun saveSources(postData: String?): ReturnData { postData ?: return ReturnData().setErrorMsg("数据不能为空") val okSources = arrayListOf() - val source = RssSource.fromJsonArray(postData).getOrNull() + val source = GSON.fromJsonArray(postData).getOrNull() if (source.isNullOrEmpty()) { return ReturnData().setErrorMsg("转换源失败") } @@ -63,7 +66,7 @@ object RssSourceController { fun deleteSources(postData: String?): ReturnData { postData ?: return ReturnData().setErrorMsg("没有传递数据") - RssSource.fromJsonArray(postData).onFailure { + GSON.fromJsonArray(postData).onFailure { return ReturnData().setErrorMsg("格式不对") }.onSuccess { it.forEach { source -> diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index d731a8a94..ca1232f7f 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -7,11 +7,9 @@ import io.legado.app.constant.AppPattern import io.legado.app.constant.BookSourceType import io.legado.app.data.entities.rule.* import io.legado.app.utils.GSON -import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonObject import io.legado.app.utils.splitNotBlank import kotlinx.parcelize.Parcelize -import java.io.InputStream @Suppress("unused") @Parcelize @@ -220,31 +218,6 @@ data class BookSource( private fun equal(a: String?, b: String?) = a == b || (a.isNullOrEmpty() && b.isNullOrEmpty()) - companion object { - - private val gson = GSON.newBuilder() - .registerTypeAdapter(ExploreRule::class.java, ExploreRule.jsonDeserializer) - .registerTypeAdapter(SearchRule::class.java, SearchRule.jsonDeserializer) - .registerTypeAdapter(BookInfoRule::class.java, BookInfoRule.jsonDeserializer) - .registerTypeAdapter(TocRule::class.java, TocRule.jsonDeserializer) - .registerTypeAdapter(ContentRule::class.java, ContentRule.jsonDeserializer) - .registerTypeAdapter(ReviewRule::class.java, ReviewRule.jsonDeserializer) - .create() - - fun fromJson(json: String): Result { - return gson.fromJsonObject(json) - } - - fun fromJsonArray(json: String): Result> { - return gson.fromJsonArray(json) - } - - fun fromJsonArray(inputStream: InputStream): Result> { - return gson.fromJsonArray(inputStream) - } - - } - class Converters { @TypeConverter diff --git a/app/src/main/java/io/legado/app/data/entities/RssSource.kt b/app/src/main/java/io/legado/app/data/entities/RssSource.kt index 95184d7e6..6c87f1213 100644 --- a/app/src/main/java/io/legado/app/data/entities/RssSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/RssSource.kt @@ -2,9 +2,12 @@ package io.legado.app.data.entities import android.os.Parcelable import android.text.TextUtils -import androidx.room.* +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.Index +import androidx.room.PrimaryKey import io.legado.app.constant.AppPattern -import io.legado.app.utils.* +import io.legado.app.utils.splitNotBlank import kotlinx.parcelize.Parcelize @Parcelize @@ -168,17 +171,4 @@ data class RssSource( } } - @Suppress("MemberVisibilityCanBePrivate") - companion object { - - fun fromJson(json: String): Result { - return GSON.fromJsonObject(json) - } - - fun fromJsonArray(jsonArray: String): Result> { - return GSON.fromJsonArray(jsonArray) - } - - } - } diff --git a/app/src/main/java/io/legado/app/data/entities/rule/BookInfoRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/BookInfoRule.kt index 513696703..54fd63900 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/BookInfoRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/BookInfoRule.kt @@ -2,7 +2,7 @@ package io.legado.app.data.entities.rule import android.os.Parcelable import com.google.gson.JsonDeserializer -import io.legado.app.utils.GSON +import io.legado.app.utils.INITIAL_GSON import kotlinx.parcelize.Parcelize /** @@ -28,8 +28,11 @@ data class BookInfoRule( val jsonDeserializer = JsonDeserializer { json, _, _ -> when { - json.isJsonObject -> GSON.fromJson(json, BookInfoRule::class.java) - json.isJsonPrimitive -> GSON.fromJson(json.asString, BookInfoRule::class.java) + json.isJsonObject -> INITIAL_GSON.fromJson(json, BookInfoRule::class.java) + json.isJsonPrimitive -> INITIAL_GSON.fromJson( + json.asString, + BookInfoRule::class.java + ) else -> null } } diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ContentRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/ContentRule.kt index ca8db8ece..135472f2a 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/ContentRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/ContentRule.kt @@ -2,7 +2,7 @@ package io.legado.app.data.entities.rule import android.os.Parcelable import com.google.gson.JsonDeserializer -import io.legado.app.utils.GSON +import io.legado.app.utils.INITIAL_GSON import kotlinx.parcelize.Parcelize /** @@ -25,8 +25,11 @@ data class ContentRule( val jsonDeserializer = JsonDeserializer { json, _, _ -> when { - json.isJsonObject -> GSON.fromJson(json, ContentRule::class.java) - json.isJsonPrimitive -> GSON.fromJson(json.asString, ContentRule::class.java) + json.isJsonObject -> INITIAL_GSON.fromJson(json, ContentRule::class.java) + json.isJsonPrimitive -> INITIAL_GSON.fromJson( + json.asString, + ContentRule::class.java + ) else -> null } } diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ExploreRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/ExploreRule.kt index 6b6bfd584..6871515ea 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/ExploreRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/ExploreRule.kt @@ -2,7 +2,7 @@ package io.legado.app.data.entities.rule import android.os.Parcelable import com.google.gson.JsonDeserializer -import io.legado.app.utils.GSON +import io.legado.app.utils.INITIAL_GSON import kotlinx.parcelize.Parcelize /** @@ -26,8 +26,11 @@ data class ExploreRule( val jsonDeserializer = JsonDeserializer { json, _, _ -> when { - json.isJsonObject -> GSON.fromJson(json, ExploreRule::class.java) - json.isJsonPrimitive -> GSON.fromJson(json.asString, ExploreRule::class.java) + json.isJsonObject -> INITIAL_GSON.fromJson(json, ExploreRule::class.java) + json.isJsonPrimitive -> INITIAL_GSON.fromJson( + json.asString, + ExploreRule::class.java + ) else -> null } } diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt index c2a26203f..7d1c22b20 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt @@ -2,7 +2,7 @@ package io.legado.app.data.entities.rule import android.os.Parcelable import com.google.gson.JsonDeserializer -import io.legado.app.utils.GSON +import io.legado.app.utils.INITIAL_GSON import kotlinx.parcelize.Parcelize @Parcelize @@ -25,8 +25,8 @@ data class ReviewRule( val jsonDeserializer = JsonDeserializer { json, _, _ -> when { - json.isJsonObject -> GSON.fromJson(json, ReviewRule::class.java) - json.isJsonPrimitive -> GSON.fromJson(json.asString, ReviewRule::class.java) + json.isJsonObject -> INITIAL_GSON.fromJson(json, ReviewRule::class.java) + json.isJsonPrimitive -> INITIAL_GSON.fromJson(json.asString, ReviewRule::class.java) else -> null } } diff --git a/app/src/main/java/io/legado/app/data/entities/rule/SearchRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/SearchRule.kt index 34b9c0cd4..ba8cda454 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/SearchRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/SearchRule.kt @@ -2,7 +2,7 @@ package io.legado.app.data.entities.rule import android.os.Parcelable import com.google.gson.JsonDeserializer -import io.legado.app.utils.GSON +import io.legado.app.utils.INITIAL_GSON import kotlinx.parcelize.Parcelize /** @@ -28,8 +28,8 @@ data class SearchRule( val jsonDeserializer = JsonDeserializer { json, _, _ -> when { - json.isJsonObject -> GSON.fromJson(json, SearchRule::class.java) - json.isJsonPrimitive -> GSON.fromJson(json.asString, SearchRule::class.java) + json.isJsonObject -> INITIAL_GSON.fromJson(json, SearchRule::class.java) + json.isJsonPrimitive -> INITIAL_GSON.fromJson(json.asString, SearchRule::class.java) else -> null } } diff --git a/app/src/main/java/io/legado/app/data/entities/rule/TocRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/TocRule.kt index a8061a72f..bdf5a1a65 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/TocRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/TocRule.kt @@ -2,7 +2,7 @@ package io.legado.app.data.entities.rule import android.os.Parcelable import com.google.gson.JsonDeserializer -import io.legado.app.utils.GSON +import io.legado.app.utils.INITIAL_GSON import kotlinx.parcelize.Parcelize @Parcelize @@ -22,8 +22,8 @@ data class TocRule( val jsonDeserializer = JsonDeserializer { json, _, _ -> when { - json.isJsonObject -> GSON.fromJson(json, TocRule::class.java) - json.isJsonPrimitive -> GSON.fromJson(json.asString, TocRule::class.java) + json.isJsonObject -> INITIAL_GSON.fromJson(json, TocRule::class.java) + json.isJsonPrimitive -> INITIAL_GSON.fromJson(json.asString, TocRule::class.java) else -> null } } diff --git a/app/src/main/java/io/legado/app/help/DefaultData.kt b/app/src/main/java/io/legado/app/help/DefaultData.kt index 1d3079668..cc94b65b8 100644 --- a/app/src/main/java/io/legado/app/help/DefaultData.kt +++ b/app/src/main/java/io/legado/app/help/DefaultData.kt @@ -79,7 +79,7 @@ object DefaultData { appCtx.assets.open("defaultData${File.separator}rssSources.json") .readBytes() ) - RssSource.fromJsonArray(json).getOrDefault(emptyList()) + GSON.fromJsonArray(json).getOrDefault(emptyList()) } val coverRule: BookCover.CoverRule by lazy { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt index c0388579b..3e148a97c 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt @@ -191,7 +191,7 @@ class ImportBookSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_vie override fun onCodeSave(code: String, requestId: String?) { requestId?.toInt()?.let { - BookSource.fromJson(code).getOrNull()?.let { source -> + GSON.fromJsonObject(code).getOrNull()?.let { source -> viewModel.allSources[it] = source adapter.setItem(it, source) } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt index 620c25254..6a0969ec4 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt @@ -98,26 +98,27 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { kotlin.runCatching { val json = JsonPath.parse(mText) json.read>("$.sourceUrls") - }.onSuccess { - it.forEach { + }.onSuccess { listUrl -> + listUrl.forEach { importSourceUrl(it) } }.onFailure { - BookSource.fromJson(mText).getOrThrow().let { + GSON.fromJsonObject(mText).getOrThrow().let { allSources.add(it) } } } - mText.isJsonArray() -> BookSource.fromJsonArray(mText).getOrThrow().let { items -> - allSources.addAll(items) - } + mText.isJsonArray() -> GSON.fromJsonArray(mText).getOrThrow() + .let { items -> + allSources.addAll(items) + } mText.isAbsUrl() -> { importSourceUrl(mText) } mText.isUri() -> { val uri = Uri.parse(mText) uri.inputStream(context).getOrThrow().let { - allSources.addAll(BookSource.fromJsonArray(it).getOrThrow()) + allSources.addAll(GSON.fromJsonArray(it).getOrThrow()) } } else -> throw NoStackTraceException(context.getString(R.string.wrong_format)) @@ -139,7 +140,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { url(url) } }.byteStream().let { - allSources.addAll(BookSource.fromJsonArray(it).getOrThrow()) + allSources.addAll(GSON.fromJsonArray(it).getOrThrow()) } } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt index eff9a6d18..8bd3650e5 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt @@ -190,7 +190,7 @@ class ImportRssSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_view override fun onCodeSave(code: String, requestId: String?) { requestId?.toInt()?.let { - RssSource.fromJson(code).getOrNull()?.let { source -> + GSON.fromJsonObject(code).getOrNull()?.let { source -> viewModel.allSources[it] = source adapter.setItem(it, source) } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt index 51e421ab1..11b7695b3 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt @@ -98,13 +98,13 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { importSourceUrl(it) } } else { - RssSource.fromJsonArray(mText).getOrThrow().let { + GSON.fromJsonArray(mText).getOrThrow().let { allSources.addAll(it) } } } mText.isJsonArray() -> { - RssSource.fromJsonArray(mText).getOrThrow().let { + GSON.fromJsonArray(mText).getOrThrow().let { allSources.addAll(it) } } @@ -132,7 +132,7 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { val items: List> = jsonPath.parse(body).read("$") for (item in items) { val jsonItem = jsonPath.parse(item) - RssSource.fromJson(jsonItem.jsonString()).getOrThrow().let { source -> + GSON.fromJsonObject(jsonItem.jsonString()).getOrThrow().let { source -> allSources.add(source) } } diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt index 4b58a8480..e51d9b4c6 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt @@ -96,7 +96,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat val jsonItem = jsonPath.parse(items[0]) ImportOldData.fromOldBookSource(jsonItem) } else { - BookSource.fromJsonArray(text).getOrThrow()[0] + GSON.fromJsonArray(text).getOrThrow()[0] } } text.isJsonObject() -> { @@ -104,7 +104,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat val jsonItem = jsonPath.parse(text) ImportOldData.fromOldBookSource(jsonItem) } else { - BookSource.fromJson(text).getOrThrow() + GSON.fromJsonObject(text).getOrThrow() } } else -> throw NoStackTraceException("格式不对") diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt index 74a3696fc..98632b9b1 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt @@ -9,11 +9,8 @@ import io.legado.app.data.entities.RssSource import io.legado.app.exception.NoStackTraceException import io.legado.app.help.RuleComplete import io.legado.app.help.http.CookieStore -import io.legado.app.utils.getClipText -import io.legado.app.utils.printOnDebug -import io.legado.app.utils.stackTraceStr +import io.legado.app.utils.* -import io.legado.app.utils.toastOnUi import kotlinx.coroutines.Dispatchers @@ -57,7 +54,7 @@ class RssSourceEditViewModel(application: Application) : BaseViewModel(applicati execute(context = Dispatchers.Main) { var source: RssSource? = null context.getClipText()?.let { json -> - source = RssSource.fromJson(json).getOrThrow() + source = GSON.fromJsonObject(json).getOrThrow() } source }.onError { @@ -74,7 +71,7 @@ class RssSourceEditViewModel(application: Application) : BaseViewModel(applicati fun importSource(text: String, finally: (source: RssSource) -> Unit) { execute { val text1 = text.trim() - RssSource.fromJson(text1).getOrThrow().let { + GSON.fromJsonObject(text1).getOrThrow().let { finally.invoke(it) } }.onError { diff --git a/app/src/main/java/io/legado/app/utils/GsonExtensions.kt b/app/src/main/java/io/legado/app/utils/GsonExtensions.kt index b446f01a9..bf2868789 100644 --- a/app/src/main/java/io/legado/app/utils/GsonExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/GsonExtensions.kt @@ -13,8 +13,7 @@ import java.lang.reflect.ParameterizedType import java.lang.reflect.Type import kotlin.math.ceil - -val GSON: Gson by lazy { +val INITIAL_GSON by lazy { GsonBuilder() .registerTypeAdapter( object : TypeToken?>() {}.type, @@ -27,6 +26,17 @@ val GSON: Gson by lazy { .create() } +val GSON: Gson by lazy { + INITIAL_GSON.newBuilder() + .registerTypeAdapter(ExploreRule::class.java, ExploreRule.jsonDeserializer) + .registerTypeAdapter(SearchRule::class.java, SearchRule.jsonDeserializer) + .registerTypeAdapter(BookInfoRule::class.java, BookInfoRule.jsonDeserializer) + .registerTypeAdapter(TocRule::class.java, TocRule.jsonDeserializer) + .registerTypeAdapter(ContentRule::class.java, ContentRule.jsonDeserializer) + .registerTypeAdapter(ReviewRule::class.java, ReviewRule.jsonDeserializer) + .create() +} + inline fun genericType(): Type = object : TypeToken() {}.type inline fun Gson.fromJsonObject(json: String?): Result {