Skip to content

DataBooth/mojo-toml

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

44 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

mojo-toml ๐Ÿ”ฅ

Native TOML 1.0 parser and writer for Mojo

Status: ๐Ÿš€ v0.5.0 - TOML 1.0 Complete + Partial 1.1 (168 tests passing)

Overview

mojo-toml enables native TOML parsing in Mojo without Python dependencies. Parse configuration files, project settings, and structured data with a clean, type-safe API.

Key features:

  • โœ… TOML 1.0 compliant - full specification support
  • โœ… Array of tables - [[section]] syntax for repeated table arrays
  • โœ… Alternative number bases - hex (0xDEAD), octal (0o755), binary (0b1101)
  • โœ… TOML writer - serialize Dict back to TOML format with round-trip fidelity
  • โœ… Nested structures - dotted keys and table headers
  • โœ… 168 comprehensive tests - parser (127) + writer (41)
  • โœ… Zero Python dependencies - pure native Mojo implementation

Quickstart

Create a TOML file (e.g examples/quickstart.toml):

# Application configuration
[app]
name = "QuickStart"
version = "1.0.0"
debug = false

[database]
host = "localhost"
port = 5432
timeout = 30.5

[features]
enabled = ["auth", "logging", "metrics"]

Reading TOML

Parse it with mojo-toml:

from toml import parse

fn main() raises:
    # Read TOML file
    var content: String
    with open("examples/quickstart.toml", "r") as f:
        content = f.read()
    
    # Parse and access values
    var config = parse(content)
    
    # Access nested tables
    var app = config["app"].as_table()
    print("App:", app["name"].as_string())
    print("Version:", app["version"].as_string())
    
    var db = config["database"].as_table()
    print("Database:", db["host"].as_string(), ":", db["port"].as_int())
    print("Timeout:", db["timeout"].as_float())
    
    # Access arrays
    var features = config["features"].as_table()["enabled"].as_array()
    print("Features enabled:", len(features))

Writing TOML

Create configuration programmatically and write to TOML:

from toml import to_toml, TomlValue

fn main() raises:
    # Build configuration using Dict and TomlValue
    var config = Dict[String, TomlValue]()
    
    # Create app section
    var app = Dict[String, TomlValue]()
    app["name"] = TomlValue("QuickStart")
    app["version"] = TomlValue("2.0.0")
    app["debug"] = TomlValue(True)
    config["app"] = TomlValue(app^)
    
    # Create database section
    var db = Dict[String, TomlValue]()
    db["host"] = TomlValue("localhost")
    db["port"] = TomlValue(5432)
    db["timeout"] = TomlValue(30.5)
    config["database"] = TomlValue(db^)
    
    # Create features array
    var enabled = List[TomlValue]()
    enabled.append(TomlValue("auth"))
    enabled.append(TomlValue("logging"))
    enabled.append(TomlValue("metrics"))
    var features = Dict[String, TomlValue]()
    features["enabled"] = TomlValue(enabled^)
    config["features"] = TomlValue(features^)
    
    # Convert to TOML and write to file
    var toml_str = to_toml(config)
    with open("output.toml", "w") as f:
        f.write(toml_str)
    
    print("Configuration written to output.toml")

Note for Python users: Unlike Python's tomli where you access values directly (config["app"]["name"]), mojo-toml requires explicit type conversions (.as_table(), .as_string(), etc.) because Mojo is statically typed. This provides type safety and clear error messages at the cost of slightly more verbose code.

Try it yourself: This example is available as examples/quickstart.mojo. Run it with:

pixi run example-quickstart

Future: Type-Safe Configs ๐ŸŽฏ

We're tracking Mojo's reflection capabilities for automatic struct serialisation:

// Future API (v0.8.0+)
struct Config:
    var name: String
    var port: Int
    var debug: Bool

var config = from_toml[Config]("config.toml")  // No .as_*() needed!
print(config.name)  // Direct field access

This will eliminate all the .as_string(), .as_int() boilerplate. Blocked on runtime field access in Mojo's reflection module. See REFLECTION_SERIALIZATION.md for details.

Installation

Choose the installation method that best fits your workflow:

Option 1: Git Submodule (Recommended)

Best for version-controlled projects with easy updates.

# Add to your project
cd your-project
git submodule add https://github.com/databooth/mojo-toml vendor/mojo-toml

# Use in your code
mojo -I vendor/mojo-toml/src your_app.mojo

# Update to latest version
git submodule update --remote vendor/mojo-toml

Option 2: Direct Copy

Simplest method for quick projects.

# Clone and copy source
git clone https://github.com/databooth/mojo-toml
cp -r mojo-toml/src/toml your-project/lib/toml

# Use in your code
mojo -I your-project/lib your_app.mojo

Option 3: pixi (Coming Soon)

# Future installation method via modular-community channel
pixi add mojo-toml

TOML Specification Compliance

โœ… TOML 1.0 - Fully Compliant

mojo-toml implements the complete TOML 1.0 specification (https://toml.io/en/v1.0.0):

  • Basic types: strings, integers, floats, booleans
  • Strings: basic, literal, multiline (both basic and literal)
  • Numbers: integers, floats, underscores, special values (inf, nan)
  • Alternative number bases: hex (0xDEAD), octal (0o755), binary (0b1101) โœจ v0.5.0
  • Arrays: [1, 2, 3] with nesting and mixed types
  • Inline tables: {name = "value"} with nesting
  • Table headers: [section] with proper nesting
  • Array of tables: [[section]] for repeated table arrays โœจ v0.5.0
  • Dotted keys: a.b.c = "value" creating nested structures
  • Duplicate detection: validates and rejects duplicate keys
  • Error messages: precise line and column context
  • TOML writer: serialize Dict[String, TomlValue] to TOML format
  • Round-trip support: parse โ†’ modify โ†’ write โ†’ parse preserves semantic equality

Date/Time values: Parsed and validated according to TOML 1.0, returned as ISO 8601 strings. Native Mojo datetime objects are not yet used due to ongoing standard library development. This does not affect TOML parsing correctness or round-trip fidelity.

๐Ÿ”ฎ TOML 1.1 (Partial Support)

TOML 1.1 features implemented:

  • โœ… \\xHH escape sequences for codepoints 0-255 (e.g., \\x00, \\x61)
  • โœ… \\e escape for escape character (U+001B)

TOML 1.1 features not yet implemented:

  • Multiline inline tables with trailing commas
  • Optional seconds in datetime/time values

See ROADMAP.md for development timeline.

Development

Prerequisites

  • Mojo 2025/2026 (via pixi)
  • Python 3.10+ (for validation tests)

Setup

# Clone repository
git clone https://github.com/databooth/mojo-toml
cd mojo-toml

# Install dependencies
pixi install

# Run tests
pixi run test-all

# Run examples
pixi run example-simple
pixi run example-pixi

Project Structure

mojo-toml/
โ”œโ”€โ”€ src/toml/           # Source code
โ”‚   โ”œโ”€โ”€ __init__.mojo   # Public API: parse(), to_toml()
โ”‚   โ”œโ”€โ”€ lexer.mojo      # Tokenisation
โ”‚   โ”œโ”€โ”€ parser.mojo     # TOML parsing
โ”‚   โ””โ”€โ”€ writer.mojo     # TOML serialisation
โ”œโ”€โ”€ tests/              # Test suite (168 tests)
โ”œโ”€โ”€ examples/           # Usage examples
โ”œโ”€โ”€ benchmarks/         # Performance benchmarks
โ”œโ”€โ”€ fixtures/           # Test TOML files
โ”œโ”€โ”€ docs/               # Documentation
โ”‚   โ”œโ”€โ”€ PERFORMANCE.md  # Performance characteristics
โ”‚   โ””โ”€โ”€ planning/       # Planning and historical docs
โ””โ”€โ”€ packaging/          # Conda packaging files

Benchmarks

Run performance benchmarks with full system reporting:

# Mojo benchmark (mojo-toml performance)
pixi run benchmark-mojo

# Python baseline (tomllib/tomli_w comparison)
pixi run benchmark-python

Both benchmarks generate markdown reports in benchmarks/reports/ with:

  • System specifications (OS, CPU, GPU, RAM, Mojo/Python versions)
  • Performance tables with throughput and latency
  • Timestamp and machine configuration

See PERFORMANCE.md for detailed results and analysis.

Documentation

Contributing

Contributions welcome! This project is open source (MIT License).

How to contribute:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Run pixi run test-all to ensure tests pass
  5. Submit a pull request

See ROADMAP.md for areas where contributions would be most valuable.

Related Projects

Other Mojo Config Libraries:

  • mojo-ini - INI file parser with Python configparser compatibility
  • mojo-dotenv - Load environment variables from .env files

Other TOML Parsers in Mojo:

  • decimojo/tomlmojo - Lightweight TOML parser (~900 LOC, parser-only) embedded in the decimojo library. Good choice if you only need basic config reading for tests and don't need a standalone package or TOML 1.0 features.

Acknowledgements

Special thanks to:

  • DataBooth - Project sponsor, building high-performance data and AI services with Mojo
  • Python tomli - Reference implementation for validation
  • TOML Specification - Tom Preston-Werner's excellent config format
  • Modular Team - For creating the Mojo programming language

License

MIT License - See LICENSE for details.

Links

About

๐Ÿ”ฅ The first native TOML 1.0 parser and writer for Mojo - zero Python dependencies

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •