diff options
| author | Linnea Gräf <nea@nea.moe> | 2024-04-06 01:12:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-06 01:12:24 +0200 |
| commit | 6c088c46709a84cf6ae6ec0b35be9d25278784c7 (patch) | |
| tree | abc3f00e07976b0072c3895333707eed4aee7435 /src/main/java/at/hannibal2/skyhanni/utils | |
| parent | aff767bb841f5e2d502c8ac0cf69e9a3c0d5781f (diff) | |
| download | skyhanni-6c088c46709a84cf6ae6ec0b35be9d25278784c7.tar.gz skyhanni-6c088c46709a84cf6ae6ec0b35be9d25278784c7.tar.bz2 skyhanni-6c088c46709a84cf6ae6ec0b35be9d25278784c7.zip | |
Backend: Add feature toggle adapter to automatically turn on features (#581)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/utils')
| -rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/FeatureTogglesByDefaultAdapter.kt | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/FeatureTogglesByDefaultAdapter.kt b/src/main/java/at/hannibal2/skyhanni/utils/FeatureTogglesByDefaultAdapter.kt new file mode 100644 index 000000000..011dcc10c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/FeatureTogglesByDefaultAdapter.kt @@ -0,0 +1,79 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.config.FeatureToggle +import com.google.gson.Gson +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive +import com.google.gson.TypeAdapter +import com.google.gson.TypeAdapterFactory +import com.google.gson.internal.bind.JsonTreeReader +import com.google.gson.reflect.TypeToken +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonToken +import com.google.gson.stream.JsonWriter +import java.lang.reflect.Field +import java.lang.reflect.Type +import com.google.gson.internal.`$Gson$Types` as InternalGsonTypes + +object FeatureTogglesByDefaultAdapter : TypeAdapterFactory { + fun <T> getType(typeToken: TypeToken<T>, field: Field): Type { + return InternalGsonTypes.resolve(typeToken.type, typeToken.rawType, field.genericType) + } + + class Adapter<T>( + val originalWrite: TypeAdapter<T>, + val clazz: Class<T>, + val gson: Gson, + val type: TypeToken<T>, + ) : TypeAdapter<T>() { + override fun write(out: JsonWriter, value: T) { + // Delegate the original config write, since that one is unchanged + originalWrite.write(out, value) + } + + override fun read(reader: JsonReader): T { + reader.beginObject() + // Create a default initialized instance + val obj = clazz.newInstance() + + // Overwrite the default with true (or false) for feature toggles + clazz.fields.forEach { + val featureToggle = it.getAnnotation(FeatureToggle::class.java) + val adapt = gson.getAdapter(TypeToken.get(getType(type, it))) + if (featureToggle != null) + it.set(obj, adapt.read(JsonTreeReader(JsonPrimitive(featureToggle.trueIsEnabled)))) + if (adapt is Adapter) { + it.set(obj, adapt.read(JsonTreeReader(JsonObject()))) + } + } + + // Read the actual JSON Object + while (reader.peek() != JsonToken.END_OBJECT) { + val name = reader.nextName() + val field = clazz.getDeclaredField(name) + val fieldType = gson.getAdapter(TypeToken.get(getType(type, field))) + // Read the field data + val data = fieldType.read(reader) + // Set the field or override the feature toggle with the saved data, leaving only the unset feature toggles to deviate from their defaults + field.set(obj, data) + } + + reader.endObject() + return obj + } + } + + override fun <T : Any?> create(gson: Gson?, type: TypeToken<T>): TypeAdapter<T>? { + gson!! + val t = type.rawType + + // Check if this object has any feature toggles present + if (t.fields.none { + it.isAnnotationPresent(FeatureToggle::class.java) || + gson.getAdapter(TypeToken.get(getType(type, it))) is Adapter + }) return null + + val originalWrite = gson.getDelegateAdapter(this, type) + return Adapter(originalWrite, t as Class<T>, gson, type) + } +}
\ No newline at end of file |
