molt

molt: TOML manipulation kit

Molt parses a TOML document into a concrete syntax representation that can be transformed and rewritten while preserving comments associated with nodes.

Path Syntax

Molt functions and operations accept a path string made up of key segments separated by . (like a.b) and array indexes in brackets (like [0] or [-1]).

Bare key segments may contain ASCII letters, digits, underscores, and dashes. Segments requiring other characters (such as spaces or dots) must be quoted with single quotes (no escape processing) or double quotes (with escape processing, e.g. \").

a.b.c.d                   // ["a", "b", "c", "d"]
a.b.-1.d                  // ["a", "b", "-1", "d"]
a.b."with space".'[3]'    // ["a", "b", "with space", "[3]"]
a.b."\e".'\e'             // ["a", "b", "\u{001b}", "\\e"]

Array indexes must be integer values within brackets and negative indexing is supported. 0 is the first value in an array or array of tables, -1 is the last value in an array or array of tables.

a.b[-1].c                 // ["a", "b", -1, "c"]
a.b[3].c                  // ["a", "b", 3, "c"]

Path resolution behaviour with key or index values that do not resolve to a logical entry in the document depends on the operation performed.

When operations are required against the document root, use an empty path string ("").

The InvalidPath variant of MoltError will be returned from molt functions if the path syntax is invalid.

In some contexts, only key paths may be provided.

Types

pub type DocumentCommentPosition {
  Header
  Trailer
}

Constructors

  • Header

    Document header comments are stored in this position before any value node. When rendered, a blank line will be placed between these comments and the first value node.

  • Trailer

    Document trailer comments are stored in this position after all value nodes. When rendered, a newline may be placed between the final value node and these comments.

Values

pub fn append(
  doc doc: types.Document,
  path path: String,
  value value: value.Value,
) -> Result(types.Document, error.MoltError)

Appends to an array at path.

path must resolve to either a value node containing an array or an array of tables. When path resolves to an array of tables, the value provided must be table-like.

pub fn concat(
  doc doc: types.Document,
  path path: String,
  values values: List(value.Value),
) -> Result(types.Document, error.MoltError)

Concatenate multiple values to an array at path.

path must resolve to either a value node containing an array or an array of tables. When path resolves to an array of tables, all entries in values must be table-like.

pub fn document_errors(
  doc: types.Document,
) -> List(types.SyntaxError)

Every validation error in the document as a fully-positioned SyntaxError, computed on demand from the current tree. Returns [] for a valid document.

This is the only path that builds error spans; parsing and construction only count, so positions are paid for solely when you ask for them here.

pub fn ensure_exists(
  doc doc: types.Document,
  path path: String,
  kind kind: types.TomlKind,
) -> Result(types.Document, error.MoltError)

Ensures that a table or array of tables exists at path.

kind must be types.Table or types.ArrayOfTables; other kinds are rejected.

If the matching structure already exists, nothing is done. If path does not resolve, an empty entry is created with implicit table ancestors as required. If path resolves to an implicit table and kind is types.Table, the implicit table is concretized into an emitted header using the key segments of path.

A TypeMismatch error is returned if path resolves to any other value shape, or if any ancestor in the path is anything other than an implicit table, concrete table, or array of tables entry.

pub fn error_count(doc: types.Document) -> Int

The number of validation errors found in the document.

pub fn get(
  doc doc: types.Document,
  path path: String,
) -> Result(value.Value, error.MoltError)

Get the value or structure at path as a molt Value.

Implicit tables are returned as table values.

pub fn get_comments(
  doc doc: types.Document,
  path path: String,
) -> Result(ops.Comments, error.MoltError)

Reads the comments attached to the node at path.

path must resolve to a concrete node (not an implicit table) or the root of the document (""); other paths return an error.

The result mirrors set_comments: leading comment lines and an optional trailing (inline) comment. Comment text is returned verbatim, including the leading #, so a value read here round-trips back through set_comments unchanged.

pub fn get_document_comments(
  doc doc: types.Document,
  at at: DocumentCommentPosition,
) -> List(String)

Reads Header or Trailer document comments.

Returns the comment lines verbatim (including the leading # but without newlines) or [] when there are no comments.

pub fn has(doc doc: types.Document, path path: String) -> Bool

Check if path exists in the document.

pub fn has_errors(doc: types.Document) -> Bool

Whether the document has any validation errors. Most document-level operations refuse to run while this is True.

pub fn insert(
  doc doc: types.Document,
  path path: String,
  before before: Int,
  value value: value.Value,
) -> Result(types.Document, error.MoltError)

Inserts a value before index before in an array at path.

path must resolve to a value node containing an array or an array of tables. When path resolves to an array of tables, value must be table-like.

pub fn insert_key(
  doc doc: types.Document,
  path path: String,
  before before: String,
  key key: String,
  value value: value.Value,
) -> Result(types.Document, error.MoltError)

Inserts a key/value pair before an existing key in the table at path.

path must resolve to a concrete table, array of tables entry, or implicit table. Both before and key are literal key names (immediate children of path). If before is not found, the entry is appended.

When path is an implicit table, the new entry is emitted as a root-level dotted key.

pub fn keys(
  doc doc: types.Document,
  path p: String,
) -> Result(List(String), error.MoltError)

Return the list of keys in a table-like value at the provided path.

pub fn length(
  doc doc: types.Document,
  path p: String,
) -> Result(Int, error.MoltError)

Return the number of entries in an array or array of tables at path.

pub fn merge_values(
  doc doc: types.Document,
  path path: String,
  entries entries: List(#(String, value.Value)),
  on_conflict on_conflict: ops.ConflictStrategy,
) -> Result(types.Document, error.MoltError)

Merge key/value entries into the resolved table at path.

path must resolve to a concrete table or an array of tables entry; implicit tables and other shapes are rejected with a TypeMismatch error.

Each key in entries is parsed as a path value relative to the table at path. Index segments in entry keys will be rejected with an InvalidPath error, and entry keys redefining any existing concrete table or value are rejected.

The on_conflict parameter controls how collisions with existing leaf keys are resolved.

pub fn move(
  doc doc: types.Document,
  from from: String,
  to to: String,
) -> Result(types.Document, error.MoltError)

Moves the node at from to to.

from must resolve to an existing node of any kind except the root. to must not already exist, and its last segment must be a key (not an index). The node is removed from from and re-inserted at to, preserving its structure.

pub fn move_comments(
  doc doc: types.Document,
  from from: String,
  to to: String,
) -> Result(types.Document, error.MoltError)

Moves comments from the node at from to the node at to.

Both from and to must resolve to concrete nodes or the root of the document ("").

pub fn move_keys(
  doc doc: types.Document,
  from from: String,
  to to: String,
  keys keys: List(String),
  on_conflict on_conflict: ops.ConflictStrategy,
) -> Result(types.Document, error.MoltError)

Moves a subset of keys from the table at from into the table at to.

from must resolve to a concrete table, implicit table, or array of tables entry. keys are literal key names naming the immediate children of the from table. Keys not present in the from table are ignored.

If to does not exist or is an implicit table, a concrete table header will be created. The on_conflict parameter controls how collisions with existing keys in the to table are resolved.

pub fn new() -> types.Document

Create an empty TOML document.

pub fn normalize(doc doc: types.Document) -> types.Document

Returns a copy of the document with its tree normalized:

  • Unix newlines (LF) throughout.
  • Table header declarations have excess leading and interior space removed.
  • Key/value pairs have excess leading space removed, a single space after the key and a single space before the value, resulting in key = value.
  • A single blank line separates table and array of tables headers.
  • Leading comments are preserved immediately before their node.
  • Trailing (inline) comments on key-value and header lines are preserved.
  • Inline arrays and tables without comments are collapsed to a single-line form.
  • The document ends with a single trailing newline.

The returned document is valid for further operations or for piping into to_string.

pub fn parse(
  source: String,
) -> Result(types.Document, error.MoltError)

Parse a TOML source string into a Document.

Returns an error if the the document cannot be parsed. Note that most documents can be parsed, but not all documents with errors produce usable or easily recoverable syntax trees.

The document’s error_count records how many validation errors were found; retrieve the full positioned list with document_errors.

The parsed document defaults to TOML 1.1 format, even if the source file was TOML 1.0.

pub fn parse_bits(
  source: BitArray,
) -> Result(types.Document, error.MoltError)

Parses a TOML source BitArray into a Document.

Returns an error if the source is not valid UTF-8 data or if the transformed UTF-8 data fails on parse.

pub fn place(
  doc doc: types.Document,
  path path: String,
  value value: value.Value,
) -> Result(types.Document, error.MoltError)

Unconditionally places value at path.

If path already exists, it is removed before writing the value. Structural Values (table, array of tables, etc.) are permitted.

pub fn remove(
  doc doc: types.Document,
  path path: String,
) -> Result(types.Document, error.MoltError)

Removes the node at path from the document.

If path resolves to an implicit table, the implicit table and all concrete nodes beneath it are removed.

pub fn rename(
  doc doc: types.Document,
  path path: String,
  to to: String,
) -> Result(types.Document, error.MoltError)

Renames the last segment of path to to.

The last segment of path must be a key. to is a literal key name and must not already exist as a sibling.

Renaming an implicit table renames all concrete descendants that reference it.

pub fn representation(
  doc doc: types.Document,
  path path: String,
  form form: ops.Form,
) -> Result(types.Document, error.MoltError)

Converts the structure at path between inline and block forms.

path must resolve to a table or array of tables. The data is preserved; only the representation changes (inline table ↔ table section, array of inline tables ↔ array of tables entries).

A path that does not reference a convertible structure is a TypeMismatch. Conversions that would produce invalid TOML (e.g., inlining a table with sub-table descendants) are rejected.

pub fn run(
  doc doc: types.Document,
  ops ops: List(ops.Operation),
) -> Result(types.Document, error.MoltError)

Execute a batch of Operations over a Document where all operations must succeed for an update.

Operations will not run over a Document with errors.

pub fn set(
  doc doc: types.Document,
  path path: String,
  value value: value.Value,
) -> Result(types.Document, error.MoltError)

Sets a value at path in the document.

Creates or overwrites a key/value node. If path does not exist, it is created (with implicit ancestors as needed). If path resolves to an existing value node, the value is replaced.

If path resolves to a structural node (table sections, array of tables, implicit tables), Set will return a TypeMismatch error.

pub fn set_comments(
  doc doc: types.Document,
  path path: String,
  comments comments: ops.Comments,
) -> Result(types.Document, error.MoltError)

Sets comments on the node at path.

path must resolve to a concrete node (not an implicit table) or the root of the document (""). Replaces any existing comments on the node with the provided comments.

pub fn set_document_comments(
  doc doc: types.Document,
  at at: DocumentCommentPosition,
  comments comments: List(String),
) -> types.Document

Replaces Header or Trailer document comments, returning the updated document. If the comment text does not include #, the comment text will have # prepended. Comments must not include newlines; they will be added appropriately on emit.

Passing [] clears the comments.

pub fn set_version(
  doc doc: types.Document,
  to version: types.TomlVersion,
) -> types.Document

Set the target TOML version for output.

Parsed documents default to TOML 1.1 (molt.v1_1).

pub fn to_normalized_string(doc doc: types.Document) -> String

Outputs a normalized version of the document as a string.

pub fn to_string(doc: types.Document) -> String

Generate a TOML string from the document.

If the document version is the same as the original version and no changes have been made, the original document will be reproduced exactly.

pub fn transfer(
  doc doc: types.Document,
  from from: String,
  to to: String,
  on_conflict on_conflict: ops.ConflictStrategy,
) -> Result(types.Document, error.MoltError)

Transfers all keys from from to to, then removes from.

from must resolve to a concrete or implicit table. to will be created as a concrete table if it does not exist. The on_conflict parameter controls how collisions with existing keys in to are resolved.

pub fn update(
  doc doc: types.Document,
  path path: String,
  with with: fn(value.Value) -> Result(
    value.Value,
    error.MoltError,
  ),
) -> Result(types.Document, error.MoltError)

Transforms a value in place via callback.

path must resolve to a scalar, array, or inline table value node. Structural types (concrete tables, implicit tables, array of tables) are rejected with TypeMismatch.

Transforming inline tables or arrays round-trips through Value, which loses internal comments and multiline formatting.

pub fn update_error(message: String) -> error.MoltError

Creates a MoltError for returning from Update callbacks.

Update callbacks must return Result(Value, MoltError). Use this function to signal a failure with a descriptive message.

pub const v1_0: types.TomlVersion

TOML 1.0

pub const v1_1: types.TomlVersion

TOML 1.1

Search Document