Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rust Guide: Overview

TeaLeaf is written in Rust. The tealeaf-core crate provides the full API for parsing, compiling, reading, and converting TeaLeaf documents.

Crates

CrateDescription
tealeaf-coreCore library: parser, compiler, reader, CLI, JSON conversion
tealeaf-deriveProc-macro crate: #[derive(ToTeaLeaf, FromTeaLeaf)]
tealeaf-ffiC-compatible FFI layer for language bindings

Installation

Add to your Cargo.toml:

[dependencies]
tealeaf-core = { version = "2.0.0-beta.8", features = ["derive"] }

The derive feature pulls in tealeaf-derive for proc-macro support.

Core Types

TeaLeaf

The main document type:

#![allow(unused)]
fn main() {
use tealeaf::TeaLeaf;

// Parse from text
let doc = TeaLeaf::parse("name: Alice\nage: 30")?;

// Load from file
let doc = TeaLeaf::load("data.tl")?;

// Load from JSON
let doc = TeaLeaf::from_json(json_str)?;

// With schema inference
let doc = TeaLeaf::from_json_with_schemas(json_str)?;
}

Value

The value enum representing all TeaLeaf types:

#![allow(unused)]
fn main() {
use tealeaf::Value;

pub enum Value {
    Null,
    Bool(bool),
    Int(i64),
    UInt(u64),
    Float(f64),
    String(String),
    Bytes(Vec<u8>),
    Array(Vec<Value>),
    Object(ObjectMap<String, Value>),  // IndexMap alias, preserves insertion order
    Map(Vec<(Value, Value)>),
    Ref(String),
    Tagged(String, Box<Value>),
    Timestamp(i64, i16),  // (unix_millis, tz_offset_minutes)
    JsonNumber(String),   // arbitrary-precision number (raw JSON decimal string)
}
}

Schema and Field

Schema definitions:

#![allow(unused)]
fn main() {
use tealeaf::{Schema, Field, FieldType};

let schema = Schema {
    name: "user".to_string(),
    fields: vec![
        Field { name: "id".into(), field_type: FieldType { base: "int".into(), nullable: false, is_array: false } },
        Field { name: "name".into(), field_type: FieldType { base: "string".into(), nullable: false, is_array: false } },
        Field { name: "email".into(), field_type: FieldType { base: "string".into(), nullable: true, is_array: false } },
    ],
};
}

Accessing Data

#![allow(unused)]
fn main() {
let doc = TeaLeaf::load("data.tl")?;

// Get a value by key
if let Some(Value::String(name)) = doc.get("name") {
    println!("Name: {}", name);
}

// Get a schema
if let Some(schema) = doc.schema("user") {
    for field in &schema.fields {
        println!("  {}: {}", field.name, field.field_type.base);
    }
}
}

Output Operations

#![allow(unused)]
fn main() {
let doc = TeaLeaf::load("data.tl")?;

// Compile to binary
doc.compile("data.tlbx", true)?;  // true = enable compression

// Convert to JSON
let json = doc.to_json()?;         // pretty-printed
let json = doc.to_json_compact()?;  // minified

// Convert to TeaLeaf text (with schemas)
let text = doc.to_tl_with_schemas();
}

Conversion Traits

Two traits enable Rust struct ↔ TeaLeaf conversion:

#![allow(unused)]
fn main() {
pub trait ToTeaLeaf {
    fn to_tealeaf_value(&self) -> Value;
    fn collect_schemas() -> IndexMap<String, Schema>;
    fn tealeaf_field_type() -> FieldType;
}

pub trait FromTeaLeaf: Sized {
    fn from_tealeaf_value(value: &Value) -> Result<Self, ConvertError>;
}
}

These are typically derived via #[derive(ToTeaLeaf, FromTeaLeaf)] – see Derive Macros.

Extension Trait

ToTeaLeafExt provides convenience methods for any ToTeaLeaf implementor:

#![allow(unused)]
fn main() {
pub trait ToTeaLeafExt: ToTeaLeaf {
    fn to_tealeaf_doc(&self, key: &str) -> TeaLeaf;
    fn to_tl_string(&self, key: &str) -> String;
    fn to_tlbx(&self, key: &str, path: &str, compress: bool) -> Result<()>;
    fn to_tealeaf_json(&self, key: &str) -> Result<String>;
}
}

Example:

#![allow(unused)]
fn main() {
let user = User { id: 1, name: "Alice".into(), active: true };

// One-liner serialization
let text = user.to_tl_string("user");
user.to_tlbx("user", "user.tlbx", true)?;
let json = user.to_tealeaf_json("user")?;
}

Next Steps