Build Status Coverage Status Hex version

TomlElixir is a modern, high-performance TOML parser and encoder for Elixir. It is designed to be fully compliant with the TOML specification while providing an idiomatic Elixir experience.

Features

  • Full Specification Support: Supports both TOML 1.0.0 and 1.1.0 specifications.
  • Native Elixir Types: Decodes TOML directly into native Elixir types (DateTime, NaiveDateTime, Date, Time, Float, Integer, Boolean, String, Map, List).
  • Bidirectional: Full support for both decoding (TOML to Map) and encoding (Map to TOML).
  • Strict Parsing: Comprehensive error messages for invalid TOML documents.
  • Spec Selection: Allows you to choose which TOML version to follow during decoding.
  • Struct Support: Use the TomlElixir.Encoder protocol to encode custom structs via @derive.

Installation

Add toml_elixir to your list of dependencies in mix.exs:

def deps do
  [
    {:toml_elixir, "~> 3.0.0"}
  ]
end

Usage

Decoding TOML

Convert a TOML string into an Elixir Map.

toml_string = """
title = "TOML Example"

[database]
enabled = true
ports = [ 8000, 8001, 8002 ]
temp_targets = { cpu = 79.5, case = 72.0 }
"""

# Simple decoding
{:ok, data} = TomlElixir.decode(toml_string)
data = TomlElixir.decode!(toml_string)

# Specify TOML version (default is :"1.1.0")
TomlElixir.decode(toml_string, spec: :"1.0.0")

Encoding to TOML

Convert an Elixir Map back into a valid TOML string.

data = %{
  "title" => "TOML Example",
  "database" => %{
    "enabled" => true,
    "ports" => [8000, 8001, 8002]
  }
}

{:ok, toml_string} = TomlElixir.encode(data)
toml_string = TomlElixir.encode!(data)

Encoding Structs

You can use the TomlElixir.Encoder protocol to allow your structs to be encoded as TOML.

defmodule User do
  @derive TomlElixir.Encoder
  defstruct [:name, :age]
end

user = %User{name: "Alice", age: 30}
toml_string = TomlElixir.encode!(%{user: user})
# [user]
# age = 30
# name = "Alice"

You can also choose which struct keys are encoded:

defmodule User do
  @derive {TomlElixir.Encoder, only: [:name]}
  defstruct [:name, :age, :password]
end

defmodule PublicUser do
  @derive {TomlElixir.Encoder, except: [:password]}
  defstruct [:name, :age, :password]
end

Prefer :only to avoid leaking new fields added to a struct in the future.

If you do not own the struct module, you can derive the protocol externally:

Protocol.derive(TomlElixir.Encoder, NameOfTheStruct, only: [:public_field])
Protocol.derive(TomlElixir.Encoder, NameOfTheStruct, except: [:private_field])
Protocol.derive(TomlElixir.Encoder, NameOfTheStruct)

Type Mapping

TOML TypeElixir Type
StringString.t()
IntegerInteger.t()
FloatFloat.t() (plus :infinity, :neg_infinity, :nan)
Booleanboolean()
Offset Date-TimeDateTime.t()
Local Date-TimeNaiveDateTime.t()
Local DateDate.t()
Local TimeTime.t()
ArrayList.t()
TableMap.t()
Inline TableMap.t()

Contribution

Contributions are welcome! If you find a bug or want to suggest a feature, please open an issue or submit a pull request. Make sure all tests pass before submitting.

# Run tests
mix test

# Run coverage report
mix coveralls

License

TomlElixir is released under the MIT License.