parsetoml
parsetoml
parsetoml is a small native Donna TOML parser for configuration files.
Supported:
- Basic strings with common escape sequences.
- Literal strings.
- Integers, including negative integers.
- Booleans.
- Arrays, including nested arrays.
- Inline tables.
- Table headers and nested table headers.
- Line comments and inline comments.
Not supported yet: floats, dates, multi-line strings, and
[[array-of-tables]].
import parsetoml
let src = "name = \"Donna\"\n[build]\noutput = \"public\""
let toml = parsetoml.unwrap_table(parsetoml.parse(src))
let name = parsetoml.get_string(toml, "name") |> parsetoml.unwrap_string
Types
pub type Parsed(a)Result returned by the parser and typed getter functions.
Ok(value) means the operation succeeded. Err(message) carries a human
readable parse or lookup error.
import parsetoml
pub fn parsed_ok() -> Bool:
parsetoml.parse("name = \"site\"") |> parsetoml.is_ok
Ok(a)Err(String)pub type TomlValueTOML value tree produced by parse.
Tables are represented as a list of key/value pairs. Nested sections become
nested TomlTable values.
import parsetoml
pub fn manual_value() -> parsetoml.TomlValue:
parsetoml.TomlString("hello")
TomlString(String)TomlInt(Int)TomlBool(Bool)TomlArray(List(TomlValue))TomlTable(List(#(String, TomlValue)))Functions
pub fn parse(input: String) -> Parsed(TomlValue)Parse a TOML document string into a TomlTable.
The parser returns Err(message) instead of panicking when it finds invalid
syntax. Use the typed getters to read values from the returned table.
import parsetoml
pub fn parse_name() -> String:
let toml = parsetoml.unwrap_table(parsetoml.parse("name = \"site\""))
parsetoml.get_string(toml, "name") |> parsetoml.unwrap_string
pub fn get_string(t: TomlValue, key: String) -> Parsed(String)Read a string value from a TOML table by key.
Returns an error when the key does not exist or when the value is not a
TomlString.
import parsetoml
pub fn package_name() -> String:
let toml = parsetoml.unwrap_table(parsetoml.parse("name = \"demo\""))
parsetoml.get_string(toml, "name") |> parsetoml.unwrap_string
pub fn get_int(t: TomlValue, key: String) -> Parsed(Int)Read an integer value from a TOML table by key.
Returns an error when the key does not exist or when the value is not a
TomlInt.
import parsetoml
pub fn menu_weight() -> Int:
let toml = parsetoml.unwrap_table(parsetoml.parse("weight = 10"))
parsetoml.get_int(toml, "weight") |> parsetoml.unwrap_int
pub fn get_bool(t: TomlValue, key: String) -> Parsed(Bool)Read a boolean value from a TOML table by key.
Returns an error when the key does not exist or when the value is not a
TomlBool.
import parsetoml
pub fn drafts_enabled() -> Bool:
let toml = parsetoml.unwrap_table(parsetoml.parse("draft = false"))
parsetoml.get_bool(toml, "draft") |> parsetoml.unwrap_bool
pub fn get_table(t: TomlValue, key: String) -> Parsed(TomlValue)Read a nested table from a TOML table by key.
This is used for section headers such as [build] and for inline tables
such as pkg = { path = "../pkg" }.
import parsetoml
pub fn output_dir() -> String:
let toml = parsetoml.unwrap_table(parsetoml.parse("[build]\noutput = \"public\""))
case parsetoml.get_table(toml, "build"):
parsetoml.Err(_) -> ""
parsetoml.Ok(build) ->
parsetoml.get_string(build, "output") |> parsetoml.unwrap_string
pub fn get_array(t: TomlValue, key: String) -> Parsed(List(TomlValue))Read an array value from a TOML table by key.
Arrays contain TomlValue items, so callers can pattern match on each item
to read strings, integers, booleans, nested arrays, or nested tables.
import parsetoml
pub fn first_tag() -> String:
let toml = parsetoml.unwrap_table(parsetoml.parse("tags = [\"donna\", \"toml\"]"))
case parsetoml.get_array(toml, "tags"):
parsetoml.Err(_) -> ""
parsetoml.Ok(tags) ->
case tags:
[parsetoml.TomlString(tag), .._] -> tag
_ -> ""
pub fn unwrap_table(r: Parsed(TomlValue)) -> TomlValueExtract a table from a parsed TOML result.
This helper is intentionally forgiving: it returns an empty table when the
result is an error. Use is_err and err_msg when the caller needs to
preserve parse failures.
import parsetoml
pub fn empty_on_error() -> parsetoml.TomlValue:
parsetoml.unwrap_table(parsetoml.parse("name"))
pub fn unwrap_string(r: Parsed(String)) -> StringExtract a string from a parsed string result.
This helper returns the string value on success. On error it returns a
string prefixed with __err: so test output and simple pipelines still show
the failure message.
import parsetoml
pub fn read_name() -> String:
let toml = parsetoml.unwrap_table(parsetoml.parse("name = \"site\""))
parsetoml.get_string(toml, "name") |> parsetoml.unwrap_string
pub fn unwrap_int(r: Parsed(Int)) -> IntExtract an integer from a parsed integer result.
This helper returns 0 when the result is an error. Use it when a fallback
value is acceptable.
import parsetoml
pub fn read_weight() -> Int:
let toml = parsetoml.unwrap_table(parsetoml.parse("weight = 20"))
parsetoml.get_int(toml, "weight") |> parsetoml.unwrap_int
pub fn unwrap_bool(r: Parsed(Bool)) -> BoolExtract a boolean from a parsed boolean result.
This helper returns False when the result is an error. Use it when a
missing or invalid boolean should behave like false.
import parsetoml
pub fn read_draft() -> Bool:
let toml = parsetoml.unwrap_table(parsetoml.parse("draft = true"))
parsetoml.get_bool(toml, "draft") |> parsetoml.unwrap_bool
pub fn is_ok(r: Parsed(a)) -> BoolReturn True when a parsed result is Ok.
This is useful in tests and in branches where only success/failure matters.
import parsetoml
pub fn config_is_valid() -> Bool:
parsetoml.parse("name = \"site\"") |> parsetoml.is_ok
pub fn is_err(r: Parsed(a)) -> BoolReturn True when a parsed result is Err.
import parsetoml
pub fn config_is_invalid() -> Bool:
parsetoml.parse("name") |> parsetoml.is_err
pub fn err_msg(r: Parsed(a)) -> StringReturn the error message from a parsed result.
Returns an empty string when the result is Ok.
import parsetoml
pub fn parse_error() -> String:
parsetoml.parse("name") |> parsetoml.err_msg