From dbd8ba67c6c1e91006ac098af19b6b058df14ab1 Mon Sep 17 00:00:00 2001
From: Elijah Mooring <vehmloewff@gmail.com>
Date: Wed, 2 Oct 2024 07:13:26 -0700
Subject: [PATCH] feat: Schema case fixes

---
 .../com/example/objectionapp/Providers.kt     |   7 +-
 .../java/com/example/objectionapp/Schema.kt   | 313 +++++++++---------
 .../com/example/objectionapp/StandardIcon.kt  |   6 +-
 3 files changed, 164 insertions(+), 162 deletions(-)

diff --git a/app/src/main/java/com/example/objectionapp/Providers.kt b/app/src/main/java/com/example/objectionapp/Providers.kt
index 4057994..6744465 100644
--- a/app/src/main/java/com/example/objectionapp/Providers.kt
+++ b/app/src/main/java/com/example/objectionapp/Providers.kt
@@ -117,9 +117,14 @@ fun TestProvider(controller: Controller) {
 	}
 }
 
+@Composable
+fun useController(): Controller {
+	return LocalController.current!!
+}
+
 @Composable
 fun useObject(id: String?): Object? {
-	val controller = LocalController.current!!
+	val controller = useController()
 	var obj by remember { mutableStateOf(id?.let { controller.objectStore.getCurrentObject(id) }) }
 
 	DisposableEffect(id) {
diff --git a/app/src/main/java/com/example/objectionapp/Schema.kt b/app/src/main/java/com/example/objectionapp/Schema.kt
index 09397cc..d5cf4f6 100644
--- a/app/src/main/java/com/example/objectionapp/Schema.kt
+++ b/app/src/main/java/com/example/objectionapp/Schema.kt
@@ -41,214 +41,211 @@ annotation class IsColor
 annotation class ContentKey(val key: String)
 
 fun getSchema(klass: KClass<*>): Schema {
-	return Schema(getItemSchema(serialDescriptor(klass.createType())))
+    return Schema(getItemSchema(serialDescriptor(klass.createType())))
 }
 
 @OptIn(ExperimentalSerializationApi::class)
 private fun getItemSchema(
-	descriptor: SerialDescriptor, annotations: List<Annotation> = listOf()
+    descriptor: SerialDescriptor, annotations: List<Annotation> = listOf()
 ): ItemSchema {
-	return when (descriptor.kind) {
-		StructureKind.CLASS -> getClassSchema(descriptor)
-		PrimitiveKind.STRING -> getStringSchema(annotations)
-		PrimitiveKind.DOUBLE -> ItemSchema.NumberSchema
-		PrimitiveKind.FLOAT -> ItemSchema.NumberSchema
-		PrimitiveKind.INT -> ItemSchema.NumberSchema
-		PrimitiveKind.BOOLEAN -> ItemSchema.BooleanSchema
-		StructureKind.LIST -> getListSchema(descriptor)
-		PolymorphicKind.SEALED -> getSealedSchema(descriptor)
-		SerialKind.ENUM -> throw Exception("Use a sealed class with objects instead of an enum. Failed at: $descriptor")
-		else -> throw Exception("unknown item at $descriptor")
-	}
+    return when (descriptor.kind) {
+        StructureKind.CLASS -> getClassSchema(descriptor)
+        PrimitiveKind.STRING -> getStringSchema(annotations)
+        PrimitiveKind.DOUBLE -> ItemSchema.NumberSchema
+        PrimitiveKind.FLOAT -> ItemSchema.NumberSchema
+        PrimitiveKind.INT -> ItemSchema.NumberSchema
+        PrimitiveKind.BOOLEAN -> ItemSchema.BooleanSchema
+        StructureKind.LIST -> getListSchema(descriptor)
+        PolymorphicKind.SEALED -> getSealedSchema(descriptor)
+        SerialKind.ENUM -> throw Exception("Use a sealed class with objects instead of an enum. Failed at: $descriptor")
+        else -> throw Exception("unknown item at $descriptor")
+    }
 }
 
 @OptIn(ExperimentalSerializationApi::class)
 private fun getStringSchema(annotations: List<Annotation>): ItemSchema {
-	for (annotation in annotations) {
-		when (annotation) {
-			is ObjectReference -> return ItemSchema.ReferenceSchema(
-				expectedTopLevelVariant = serialDescriptor(
-					annotation.expectedTopLevelVariant.createType()
-				).serialName
-			)
-
-			is AnyObjectReference -> return ItemSchema.ReferenceSchema(expectedTopLevelVariant = null)
-		}
-	}
-
-	return ItemSchema.StringSchema
+    for (annotation in annotations) {
+        when (annotation) {
+            is ObjectReference -> return ItemSchema.ReferenceSchema(
+                expectedTopLevelVariant = serialDescriptor(
+                    annotation.expectedTopLevelVariant.createType()
+                ).serialName
+            )
+
+            is AnyObjectReference -> return ItemSchema.ReferenceSchema(expectedTopLevelVariant = null)
+        }
+    }
+
+    return ItemSchema.StringSchema
 }
 
 @OptIn(ExperimentalSerializationApi::class)
 private fun getSealedSchema(descriptor: SerialDescriptor): ItemSchema.EnumSchema {
-	val variants = mutableListOf<EnumVariantSchema>()
-	val child = descriptor.getElementDescriptor(1)
-	var discriminatorKey: String? = null
-	var contentKey: String? = null
-
-	for (variant in child.elementDescriptors) {
-		variants.add(
-			EnumVariantSchema(
-				name = variant.serialName, description = getDescription(listOf()), // FIXME
-				type = getItemSchema(variant)
-			)
-		)
-	}
-
-	for (annotation in descriptor.annotations) {
-		if (annotation is JsonClassDiscriminator) {
-			discriminatorKey = annotation.discriminator
-		}
-		if (annotation is ContentKey) {
-			contentKey = annotation.key
-		}
-	}
-
-	if (discriminatorKey == null) {
-		throw Exception("All sealed classes must have a JsonDiscriminatorKey annotation. Failed at: $descriptor")
-	}
-
-	return ItemSchema.EnumSchema(discriminatorKey, contentKey, variants)
+    val variants = mutableListOf<EnumVariantSchema>()
+    val child = descriptor.getElementDescriptor(1)
+    var discriminatorKey: String? = null
+    var contentKey: String? = null
+
+    for (variant in child.elementDescriptors) {
+        variants.add(
+            EnumVariantSchema(
+                name = variant.serialName, description = getDescription(listOf()), // FIXME
+                type = getItemSchema(variant)
+            )
+        )
+    }
+
+    for (annotation in descriptor.annotations) {
+        if (annotation is JsonClassDiscriminator) {
+            discriminatorKey = annotation.discriminator
+        }
+        if (annotation is ContentKey) {
+            contentKey = annotation.key
+        }
+    }
+
+    if (discriminatorKey == null) {
+        throw Exception("All sealed classes must have a JsonDiscriminatorKey annotation. Failed at: $descriptor")
+    }
+
+    return ItemSchema.EnumSchema(discriminatorKey, contentKey, variants)
 }
 
 @OptIn(ExperimentalSerializationApi::class)
 private fun getListSchema(descriptor: SerialDescriptor): ItemSchema {
-	if (descriptor.elementsCount != 1) {
-		throw Exception("A list must have exactly on child element")
-	}
+    if (descriptor.elementsCount != 1) {
+        throw Exception("A list must have exactly on child element")
+    }
 
-	return ItemSchema.ListSchema(option = getItemSchema(descriptor.getElementDescriptor(0)))
+    return ItemSchema.ListSchema(option = getItemSchema(descriptor.getElementDescriptor(0)))
 }
 
 @OptIn(ExperimentalSerializationApi::class)
 private fun getClassSchema(descriptor: SerialDescriptor): ItemSchema {
-	val items = mutableListOf<StructPropertySchema>()
-
-	for (annotation in descriptor.annotations) {
-		if (annotation is IsColor) return ItemSchema.ColorSchema
-	}
-
-	for (childIndex in 0..<descriptor.elementsCount) {
-		val child = descriptor.getElementDescriptor(childIndex)
-		val annotations = descriptor.getElementAnnotations(childIndex)
-
-		items.add(
-			StructPropertySchema(
-				name = descriptor.getElementName(childIndex),
-				type = getItemSchema(child, annotations),
-				description = getDescription(annotations),
-				optional = child.isNullable
-			)
-		)
-	}
-
-	return ItemSchema.StructSchema(properties = items)
+    val items = mutableListOf<StructPropertySchema>()
+
+    for (annotation in descriptor.annotations) {
+        if (annotation is IsColor) return ItemSchema.ColorSchema
+    }
+
+    for (childIndex in 0..<descriptor.elementsCount) {
+        val child = descriptor.getElementDescriptor(childIndex)
+        val annotations = descriptor.getElementAnnotations(childIndex)
+
+        items.add(
+            StructPropertySchema(
+                name = descriptor.getElementName(childIndex),
+                type = getItemSchema(child, annotations),
+                description = getDescription(annotations),
+                optional = child.isNullable
+            )
+        )
+    }
+
+    return ItemSchema.StructSchema(properties = items)
 }
 
 private fun getDescription(annotations: List<Annotation>): String? {
-	for (annotation in annotations) {
-		if (annotation is Description) {
-			return annotation.content
-		}
-	}
+    for (annotation in annotations) {
+        if (annotation is Description) {
+            return annotation.content
+        }
+    }
 
-	return null
+    return null
 }
 
 @OptIn(ExperimentalSerializationApi::class)
 private fun getTopLevelVariant(klass: KClass<*>): String? {
-	val descriptor = serialDescriptor(klass.createType())
+    val descriptor = serialDescriptor(klass.createType())
 
-	for (annotation in descriptor.annotations) {
-		if (annotation is ObjectReference) {
-			return serialDescriptor(
-				annotation.expectedTopLevelVariant.createType()
-			).serialName
-		}
-	}
+    for (annotation in descriptor.annotations) {
+        if (annotation is ObjectReference) {
+            return serialDescriptor(
+                annotation.expectedTopLevelVariant.createType()
+            ).serialName
+        }
+    }
 
-	return null
+    return null
 }
 
 @Serializable
 data class Schema(@SerialName("object") val obj: ItemSchema) {
-	val version = "0.1"
-
-	@SerialName("initial_objects")
-	val initialObjects = listOf(
-		InitialObject(
-			id = "theme_default",
-			description = "The theme that will be applied by default to all UI elements",
-			expectedTopLevelVariant = getTopLevelVariant(Theme::class)
-		),
-		InitialObject(
-			id = "layout_default",
-			description = "The layout that will wrap everything",
-			expectedTopLevelVariant = getTopLevelVariant(Theme::class)
-		),
-	)
+    val version = "0.1"
+
+    @SerialName("initial_objects")
+    val initialObjects = listOf(
+        InitialObject(
+            id = "theme_default",
+            description = "The theme that will be applied by default to all UI elements",
+            expectedTopLevelVariant = getTopLevelVariant(Theme::class)
+        ),
+        InitialObject(
+            id = "layout_default",
+            description = "The layout that will wrap everything",
+            expectedTopLevelVariant = getTopLevelVariant(Theme::class)
+        ),
+    )
 }
 
 @Serializable
 data class InitialObject(
-	val id: String,
-	val description: String,
-	@SerialName("expected_top_level_variant") val expectedTopLevelVariant: String?,
+    val id: String,
+    val description: String,
+    @SerialName("expected_top_level_variant") val expectedTopLevelVariant: String?,
 )
 
 @OptIn(ExperimentalSerializationApi::class)
 @JsonClassDiscriminator("$")
 @Serializable
 sealed class ItemSchema {
-	@Serializable
-	@SerialName("struct")
-	data class StructSchema(
-		val properties: List<StructPropertySchema>
-	) : ItemSchema()
-
-	@Serializable
-	@SerialName("enum")
-	data class EnumSchema(
-		@SerialName("discriminator_key") val discriminatorKey: String,
-		@SerialName("content_key") val contentKey: String?,
-		val variants: List<EnumVariantSchema>
-	) : ItemSchema()
-
-	@Serializable
-	@SerialName("string")
-	data object StringSchema : ItemSchema()
-
-	@Serializable
-	@SerialName("number")
-	data object NumberSchema : ItemSchema()
-
-	@Serializable
-	@SerialName("boolean")
-	data object BooleanSchema : ItemSchema()
-
-	@Serializable
-	@SerialName("color")
-	data object ColorSchema : ItemSchema()
-
-	@Serializable
-	@SerialName("list")
-	data class ListSchema(
-		val option: ItemSchema
-	) : ItemSchema()
-
-	@Serializable
-	@SerialName("reference")
-	data class ReferenceSchema(
-		val expectedTopLevelVariant: String?
-	) : ItemSchema()
+    @Serializable
+    @SerialName("struct")
+    data class StructSchema(
+        val properties: List<StructPropertySchema>
+    ) : ItemSchema()
+
+    @Serializable
+    @SerialName("enum")
+    data class EnumSchema(
+        @SerialName("discriminator_key") val discriminatorKey: String,
+        @SerialName("content_key") val contentKey: String?,
+        val variants: List<EnumVariantSchema>
+    ) : ItemSchema()
+
+    @Serializable
+    @SerialName("string")
+    data object StringSchema : ItemSchema()
+
+    @Serializable
+    @SerialName("number")
+    data object NumberSchema : ItemSchema()
+
+    @Serializable
+    @SerialName("boolean")
+    data object BooleanSchema : ItemSchema()
+
+    @Serializable
+    @SerialName("color")
+    data object ColorSchema : ItemSchema()
+
+    @Serializable
+    @SerialName("list")
+    data class ListSchema(
+        val option: ItemSchema
+    ) : ItemSchema()
+
+    @Serializable
+    @SerialName("reference")
+    data class ReferenceSchema(
+        @SerialName("expected_top_level_variant") val expectedTopLevelVariant: String?
+    ) : ItemSchema()
 }
 
 @Serializable
 data class StructPropertySchema(
-	val name: String,
-	val description: String?,
-	val type: ItemSchema,
-	val optional: Boolean
+    val name: String, val description: String?, val type: ItemSchema, val optional: Boolean
 )
 
 @Serializable
diff --git a/app/src/main/java/com/example/objectionapp/StandardIcon.kt b/app/src/main/java/com/example/objectionapp/StandardIcon.kt
index a672f15..a48248b 100644
--- a/app/src/main/java/com/example/objectionapp/StandardIcon.kt
+++ b/app/src/main/java/com/example/objectionapp/StandardIcon.kt
@@ -14,23 +14,23 @@ import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.vector.ImageVector
 import java.lang.System.console
 
-
 @Composable
 fun StandardIcon(
     name: String,
     modifier: Modifier = Modifier,
     tint: Color = LocalContentColor.current,
 ) {
+    val logger = useController().logger.scope("StandardIcon")
     val theme = useDefaultTheme()
     val icon: ImageVector? = remember(name) {
         try {
             val cl =
                 Class.forName("androidx.compose.material.icons.${theme.iconPack.getJavaName()}.${name}Kt")
-            println(cl)
+
             val method = cl.declaredMethods.first()
             method.invoke(null, theme.iconPack.getIcons()) as ImageVector
         } catch (err: Throwable) {
-            println("Error with icon loading: $err")
+            logger.error("failed to load icon: $err")
             null
         }
     }