kaml icon indicating copy to clipboard operation
kaml copied to clipboard

Peeking, or working with subsections of YAML

Open nomisRev opened this issue 8 months ago • 2 comments

Describe the problem you'd like to solve

When parsing OpenAPI Specifications, you need to peek or be able to interact with subsections of the YAML. For example for Reference<T> where you don't know if it's an inline defined schema, or a referenced one.

schema:
  $ref: "#/components/schemas/Pets"

vs

schemas:
  Pet:
    required:
      - id
      - name
    properties:
      id:
        type: integer
        format: int64
      name:
        type:
          - string
          - integer
      tag:
        type: string

This needs to be parsed into a ReferenceOr<Schema> sealed class, with without any type markers available in the yaml.

Describe the solution you'd like

In JSON I am currently doing this:

override fun deserialize(decoder: Decoder): ReferenceOr<T> =
  when (decoder) {
    is JsonDecoder -> deserializeJson(decoder)
    is YamlInput -> deserializeYaml(decoder)
    else -> throw UnsupportedOperationException("Unsupported decoder: $decoder")
  }

private fun deserializeJson(decoder: JsonDecoder): ReferenceOr<T> {
  val json = decoder.decodeSerializableValue(JsonElement.serializer())
  return if ((json as JsonObject).contains(RefKey))
    Reference(json[RefKey]!!.jsonPrimitive.content)
  else Value(decoder.json.decodeFromJsonElement(dataSerializer, json))
}

Describe alternatives you've considered

I am not entirely sure yet if it's not possible, but I am a bit stuck while still exploring the API. It seems that you cannot ask a YamlInput to be decoded to YamlNode, like I do with Json.

This is because YamlNode itself is not a @Serializable, but there is a separate parser build for it instead. I am not entirely sure how hard, or easy, it could be to bridge this functionality. Being able to do YamlInput::decodeYamlNode would also be sufficient, since that would allow me to peek in a similar way than Json.

Additional context

If I find a solution, or a straightforward way to improve this inside the library I will update this issue and try to contribute if makes sense.

nomisRev avatar Jun 24 '24 09:06 nomisRev