LEPTRIS

Teptris — the TOML gem v0.2.47

A native C-extension binding (no FFI, no fallback) over libteptris v0.1.27. API shape and value semantics mirror the tomlib gem: offset and local datetimes become Time, dates become Date, local times stay String.

Installation

bash
gem install teptris

RubyGems resolves a prebuilt platform gem where one exists: fat gems for x86_64/aarch64 Linux (glibc and musl), macOS (x86_64/arm64) and Windows (mingw and ucrt), each carrying one extension per Ruby minor (3.3–4.0); 32-bit ARM, big-endian s390x/ppc64le and the msvcrt-era Ruby 3.0 tier are emulated or pinned builds. Every other platform gets the source gem, which compiles the vendored engine with the installing Ruby’s own toolchain — a C compiler is required, and the install fails loudly without one.

Usage

ruby
require "teptris"

Teptris::TOML.load("title = \"teptris\"\n[owner]\nname = \"t\"\n")
# => {"title" => "teptris", "owner" => {"name" => "t"}}

Teptris::TOML.dump({"title" => "teptris", "owner" => {"name" => "t"}})

begin
  Teptris::TOML.load("a = [1,")
rescue Teptris::ParseError => e
  e.line   # 1
  e.column # 8
end

Both directions are native: dump walks the object tree in C through the builder API, so the engine emitter is the single formatting source (canonical output, 3–10× tomlib per shape). End to end, load is 7–110× tomlib and 20–280× toml-rb per shape.

The value contract

TOMLRuby
offset datetimeTime (fixed offset)
local datetimeTime
local dateDate
local timeString (the tomlib contract)
integer / float / string / bool / array / tablethe obvious Ruby types

Many documents — batch and lazy

ruby
# Eager: one Array of Hashes, same datetime contract as TOML.load
docs = Teptris::TOML.load_batch(toml_strings,
                                safe_load: [Time, Date],
                                datetime_policy: :native)

# File paths
docs = Teptris::TOML.load_files(["a.toml", "b.toml", "c.toml"])

# Lazy twin: parse N eagerly, materialize only along touched paths
arr = Teptris::TOML.load_lazy_batch(toml_strings)
arr.each { |doc | doc["x"].value }

# Threaded (0.2.52+): the C parse releases the GVL — parses overlap
# across Ruby threads; materialization serializes. Opt-in, 1 = default.
docs = Teptris::TOML.load_batch(toml_strings, threads: 4)

Lazy loading

Teptris::TOML.load_lazy parses once and materializes host objects only along the paths actually touched — the complementary path when the schema is not known up front.

Schema descriptor plans

Compile a plan once, materialize only the planned keys in one native pass — Teptris::Descriptor /Teptris::TOML.load_schema (shipped since 0.2.29; the C ABI lives in libteptris teptris/plan.h). The walk returns a nested Hash with String keys and already-cast Ruby values:

ruby
DESC = Teptris::Descriptor.build(
  children: [
    { name: "id",    kind: :scalar },
    { name: "tags",  kind: :collection },          # array of scalars
    { name: "items", kind: :nested, plan: {        # table or [[aot]]
      children: [{ name: "sku", kind: :scalar }] } },
    { name: "extra", kind: :raw },                 # escape hatch: full subtree
  ])

Teptris::TOML.load_schema(toml_string, DESC)
# => {"id"=>1, "tags"=>["a","b"], "items"=>[{"sku"=>"x"}], "extra"=>{...}}
# unplanned keys never appear

Row kinds: :scalar (any TOML value),:collection (array of scalars), :nested(recurse via plan:; spans arrays of tables),:raw (the untouched subtree). Absent planned keys read asnil.

This is the curated guide. The repositories are canonical: when this page and the repo disagree, the repo wins. Full documentation lives with the source.