kaml Documentation

repository·main·Indexed 20 days ago

https://github.com/charleskorn/kaml

A YAML support library for kotlinx.serialization that enables conversion between YAML strings and Kotlin objects. It provides functionality for decoding and encoding @Serializable classes, parsing into YamlNode for raw structure traversal, configuring polymorphism styles for sealed classes, and supporting Docker Compose-style extension fields.

Tokens
1.4K
Snippets
6
Records
6
Agent score
20%

What's inside kaml

  1. Configure polymorphism styles for sealed classes

    main

    kaml supports kotlinx.serialization polymorphism for sealed and unsealed types. You can control how types are identified in YAML by setting YamlConfiguration.polymorphismStyle when creating a Yaml instance.

    Supported styles:

    1. YAML tags: Uses !<tag> to specify the type.
    2. Type property: Uses a dedicated field (e.g., type: name) to specify the type.
    @Serializable
    sealed class Server {
      @SerialName("frontend")
      @Serializable
      data class Frontend(val hostname: String) : Server()
    
      @SerialName("backend")
      @Serializable
      data class Backend(val database: String) : Server()
    }
    
    @Serializable
    data class Config(val servers: List<Server>)
    
    val config = Config(listOf(
      Frontend("a.mycompany.com"),
      Backend("db-1")
    ))
    
    // This will use the default polymorphism style
    val result = Yaml.default.encodeToString(Config.serializer(), config)
    
    println(result)
  2. Use Docker Compose-style extension fields

    main

    kaml supports extension fields (like those used in Docker Compose) where keys starting with a specific prefix are used for anchors and aliases but are not included in the deserialized object.

    To enable this, set YamlConfiguration.extensionDefinitionPrefix (e.g., to "x-"). Extension keys must be defined at the top level of a document and must be maps or objects with an anchor defined.

    x-common-labels: &common-labels
      labels:
        owned-by: myteam@mycompany.com
        cost-centre: myteam
    
    servers:
      server-a:
        <<: *common-labels
        kind: frontend
  3. Add kaml to a Gradle project

    main

    To use kaml, add the kotlinx.serialization plugin and the kaml dependency to your Gradle build script. Ensure you use the latest version available from the kaml releases page.

    // Groovy DSL
    plugins {
        id 'org.jetbrains.kotlin.jvm' version '1.4.20'
        id 'org.jetbrains.kotlin.plugin.serialization' version '1.4.20'
    }
    
    dependencies {
      implementation "com.charleskorn.kaml:kaml:<version number here>"
    }
    // Kotlin DSL
    plugins {
        kotlin("jvm") version "1.4.20"
        kotlin("plugin.serialization") version "1.4.20"
    }
    
    dependencies {
      implementation("com.charleskorn.kaml:kaml:<version number here>")
    }
  4. Parse YAML from a string to a Kotlin object

    main

    Use Yaml.default.decodeFromString to deserialize a YAML string into a Kotlin data class annotated with @Serializable.

    @Serializable
    data class Team(
        val leader: String,
        val members: List<String>
    )
    
    val input = """
            leader: Amy
            members:
              - Bob
              - Cindy
              - Dan
        """.trimIndent()
    
    val result = Yaml.default.decodeFromString(Team.serializer(), input)
    
    println(result)
  5. Serialize a Kotlin object to YAML

    main

    Use Yaml.default.encodeToString to convert a @Serializable Kotlin object into a YAML string.

    @Serializable
    data class Team(
        val leader: String,
        val members: List<String>
    )
    
    val input = Team("Amy", listOf("Bob", "Cindy", "Dan"))
    
    val result = Yaml.default.encodeToString(Team.serializer(), input)
    
    println(result)
  6. Parse YAML into a YamlNode

    main

    If you need to work with the raw YAML structure without a specific Kotlin class, use Yaml.default.parseToYamlNode. This returns a YamlNode which can be traversed using properties like yamlMap and yamlScalar.

    val input = """
            leader: Amy
            members:
              - Bob
              - Cindy
              - Dan
        """.trimIndent()
    
    val result = Yaml.default.parseToYamlNode(input)
    
    println(
        result
            .yamlMap.get<YamlList>("members")!![1]
            .yamlScalar
            .content
    )