-
Notifications
You must be signed in to change notification settings - Fork 6
Enhancement: Support validating kaml's YamlNode
#190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi, @Vampire. I appreciate your interest in the library. I had a similar use case where I had YAML files and JSON schema and needed to validate those YAML files (and it was a multiplatform project). I ended up converting YamlNode to JsonElementprivate fun YamlNode.toJsonNode(): JsonElement =
when (this) {
is YamlList ->
buildJsonArray {
items.forEach {
add(it.toJsonNode())
}
}
is YamlMap ->
buildJsonObject {
entries.forEach { (key, value) ->
put(key.content, value.toJsonNode())
}
}
is YamlNull -> JsonNull
is YamlScalar ->
content
.toBooleanStrictOrNull()
?.let(::JsonPrimitive)
?: content
.toDoubleOrNull()
?.let(::JsonPrimitive)
?: JsonPrimitive(content)
is YamlTaggedNode -> innerNode.toJsonNode()
} I need to think about how to make this possible without breaking the API much and without ending up with two different paths for |
Actually I tried to do something similar but hit the problem that Maybe one viable option could be to slightly broaden the scope of this lib and support validating Kotlin object tree of Map, List, and so on. What I do right now is using https://github.com/krzema12/snakeyaml-engine-kmp (which kaml uses under the hood too) to parse/load the file, then transform the result to But would be awesome if I could give the load result directly even if it is not coming from KxS. You could either transform to |
I think the problem might be partially solved if the kaml (and probably SnakeKMP - I think it already does) would expose the information about ScalarStyle and block style. In this case, there would be a way to identify if the scalar is 100% a string when it has the ScalarStyle other than Plain or has a block style (am I missing something here?). But I have some doubts about block style. For example, is it a valid number? key: >
10 However, it will also require providing some API to ask the element: can you be a number? can you be a boolean? This part should be implemented here, inside the validation library, - currently, it relies on If my understanding is correct, for a YAML scalar it would be like:
@Vampire what do you think of the above? Am I missing something? |
I'm not an expert in YAML (although I tend to work on projects touching YAML 😅). From my experience, when I was trying to fix various YAML-related issues, I played with various modes of emitting the values in kaml/snakeyaml-engine. That's why I'm afraid certain assumptions may be valid for most cases, but invalid for some edge cases. Unfortunately I don't have enough capacity to dive deeper into this problem now, sorry! Maybe @aSemy has some thoughts as he ported a much bigger portion of snakeyaml-engine to snakeyaml-engine-kmp. |
kaml would probably need For now I switched to using private fun Any?.toJsonElement(): JsonElement {
return when (this) {
is Map<*, *> -> JsonObject(entries.associate { (key, value) -> "$key" to value.toJsonElement() })
is List<*> -> JsonArray(map { it.toJsonElement() })
is Set<*> -> JsonArray(map { it.toJsonElement() })
is Boolean -> JsonPrimitive(this)
is Number -> JsonPrimitive(this)
is String -> JsonPrimitive(this)
is ByteArray -> JsonPrimitive(encodeBase64())
null -> JsonNull
else -> error("Unexpected type: ${this::class.qualifiedName}")
}
} I've sent the whole Coming from The only thing in YAML it seems that has no match in JSON is the byte array which in JSON then just is Base64 encoded String according to the So if you would indeed go the "slightly broaden scope" approach mentioned above, the types from my |
UPD: corrected the links Hi, @Vampire. I would much appreciate it if you had a chance to look at a few files in the PR from an end-user perspective - I am not the one who uses the library and might be missing something:
I think that should be enough to support YAML (once kaml exposes everything needed) and also to validate the result of SnakeKMP parser (from your example above). |
To be honest, I don't see any actual way to support the Kaml at the moment - an attempt to add What I can do is create a new module in this repo with its own Alternative way (the only one I can see right now) - rework the
This will definitely break someone else's code but after that, it should be much simpler to make changes to the |
The abstraction interface will be available in |
I've had a cursory look. But again, I'm not a Kotlin expert and probably just don't know how you idiomatically design an API in Kotlin.
Well, yeah, that's the price you have to pay when you put data classes into your API.
Well, you have to talk to kaml maintainer what he would prefer. :-) |
Thank you for taking the time to check the changes @Vampire.
The more I look at this property the more I agree with you. Looks a bit strange. The original idea was to have
Did not think about it. Maybe you are right and it will look better (1 property instead of 2)
The idea was to make it similar to
The only reason for that is
Unfortunately, the With regards to the Kaml - the main problem is the functional compatibility. By adding a new property to the data class you also change the |
Ah, I see. |
Please, be aware that the |
Oh, I just found another potential sub-task / integration. :-) |
Is there an existing issue for this?
Enhancement description
Like the built-in JSON format, there is https://github.com/charleskorn/kaml for parsing YAML using KxS.
Like the
JsonElement
of the JSON format, there isYamlNode
there.Would be very nice if you could support validating those too.
Sub-tasks
YamlScalar
node to identify whether it is a string or not (currently impossible without breaking the API)The text was updated successfully, but these errors were encountered: