Ricky12Awesome / json-schema-serialization

Adds support for Json Schema using Kotlin.serialization
MIT License
30 stars 9 forks source link

Polymorphism #1

Open NikkyAI opened 4 years ago

NikkyAI commented 4 years ago

i want to use sealed classes in lists or use type Any and allow strings or objects in a list

can this library generate the correct schema for that?

or is there annotations to tell the library which schemas it should generate on a unclear and wider datatype.. like Any or a interface ?

eg:

@Serializable
data class Config(
    val entries: List<Entry>
)

@Serializable
sealed class Entry {
    data class EntryA(
        val a: String
    ): Entry
    data class EntryB(
        val b: Int
    ): Entry
}
NikkyAI commented 4 years ago

i noticed that currently contains for arrays is not generated properly so i tried doign that using the dsl myself

        val schema = buildJsonSchema {
            property("authors", String.serializer().list, true) {
                contents["type"] = JsonLiteral("array")
                contents["contains"] = JsonObject(mapOf("type" to JsonLiteral("string")))
            }
        }

this throws a StackOverflowError

Ricky12Awesome commented 3 years ago

I know I'm a bit late to this, but I fixed this in v0.6.2, atm this version doesn't have DSL, but will be added back in 0.7

NikkyAI commented 3 years ago

could it be that jss has issues with recursion?

i am now trying something along the lines of

@Serializable
sealed class NestedEntry(
    val entries: Map<String, NestedEntry> = mapOf()
) {
    @Serializable
    @SerialName("a")
    class A() : NestedEntry() {

    }

    @Serializable
    @SerialName("b")
    class B() : NestedEntry() {

    }
}

and it still runs into a StackOverflowError

PS: on a flat structure i get everything working

Ricky12Awesome commented 3 years ago

for nested values to work, I would have to implement definitions and use references, for that I need to do a re-write how it generates schema, which would be a good idea since it will also cut down on duplicates, since it can just grab it from definitions.

Ricky12Awesome commented 3 years ago

Try 0.6.4, Nested values should work, but now everything will be referenced from definitions.

NikkyAI commented 3 years ago

i also added references todefinitions in my local fork yesterday

whaty i am having issues with is.. how can i use annoations like this? Map<@StringENum(["value"]String,@IntRange(0,100)Int> in serialization?

it seems to be allowed by the language and there is a annotation target for it but no clue how to access them

Ricky12Awesome commented 3 years ago

Don't think there is a way, think that's only for custom serializers. val stuff: List<@Serializer(CustomSerializer::class) String>

NikkyAI commented 3 years ago

another small question.. how do i apply a StringEnum on a List<String> ? since there is no way to apply it to value paramters and it seems to get ignore on a list and even if it did not .. once you have a Map<K,V> which is meant with the annotation ?

can i make some temporary type for String that i can apply the annotation to ?

best would be List<@JsonSchema.StringEnum(["a", "b", "c"]) String> if thats doable at all, i know there is a annotation target for it .. but if its not retrievable from code then.. why would there be AnnotationTarget.TYPE?

the next best thing would be wrappers like @List(element = [JsonSchema.StringEnum(["a", "b", "c"]]) and @Map(key=[], value=[]) that can then be passed into the createJsonSchema function