molt: TOML Transformed

Hex.pm Hex Docs Apache 2.0 Erlang Compatible JavaScript Compatible

Molt is a TOML transformation library intended to help tool authors make modifications to configuration TOML files without accidentally affecting any comments or formatting that preexists. Molt provides complete TOML 1.0 and 1.1 specification compliance. It provides both logical and structural manipulation API surfaces.

gleam add molt@1
import molt
import molt/value

const config = "[server]
host = \"localhost\"
port = 8080

# TLS settings
[server.tls]
enabled = false
"

pub fn main() {
  let assert Ok(doc) = molt.parse(config)

  // Read a value
  let assert Ok(port) = molt.get(doc, "server.port")
  let assert Ok(8080) = value.unwrap_int(port)

  // Edit: change port and enable TLS — comments and formatting preserved
  let assert Ok(doc) = molt.set(doc, "server.port", value.int(443))
  let assert Ok(doc) = molt.set(doc, "server.tls.enabled", value.bool(True))

  molt.to_string(doc)
  // [server]
  // host = "localhost"
  // port = 443
  //
  // # TLS settings
  // [server.tls]
  // enabled = true
}

Learn more about how Molt works in the Usage Guide and the Operations Guide before reading the rest of the documentation.

Batch Edits

import molt
import molt/ops
import molt/value

const input = "[database]
host = \"db.internal\"
port = 5432
pool_size = 10
timeout = 30

[database.replica]
host = \"replica.internal\"
port = 5432
"

pub fn main() {
  let assert Ok(doc) = molt.parse(input)

  // Rename a key, move settings between tables, convert to inline
  let assert Ok(doc) =
    molt.run(doc, [
      ops.Rename(path: "database.host", to: "hostname"),
      ops.MoveKeys(
        from: "database",
        to: "database.replica",
        keys: ["pool_size", "timeout"],
        on_conflict: ops.OnConflictSkip,
      ),
      ops.Representation(path: "database.replica", form: ops.Inline),
    ])

  molt.to_string(doc)
}

Invalid TOML Recovery

When molt.parse encounters invalid values, it still returns a usable tree. The CST layer lets you surgically fix the broken node:

import gleam/result
import molt
import molt/cst
import molt/types.{KeySegment}
import molt/value

pub fn main() {
  // pi = 3..14 is not a valid TOML float
  let assert Ok(doc) = molt.parse("pi = 3..14\n")
  assert molt.has_errors(doc)

  // Fix via CST: replace the bad value, keeping the key and formatting
  let assert Ok(tree) =
    cst.from_document(doc)
    |> cst.update(path: [KeySegment("pi")], with: fn(kv) {
      let assert Ok(fixed) =
        cst.set_kv_value(kv:, value: value.to_cst(value.float(3.14)))
      fixed
    })

  let doc = cst.to_document(tree)
  assert !molt.has_errors(doc)
  molt.to_string(doc)
  // -> "pi = 3.14\n"
}

This can be explored more completely with the Repairing Invalid TOML guide.

Semantic Versioning

molt follows Semantic Versioning 2.0.

Search Document