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

.NET Guide: Overview

TeaLeaf provides .NET bindings through a NuGet package that includes a C# source generator and a reflection-based serializer, both backed by the native Rust library via P/Invoke.

Architecture

┌─────────────────────────────────────────────┐
│  Your .NET Application                      │
├─────────────────────┬───────────────────────┤
│  Source Generator   │  Reflection Serializer│
│  (compile-time)     │  (runtime)            │
├─────────────────────┴───────────────────────┤
│  TeaLeaf Managed Layer (TLDocument, TLValue)│
├─────────────────────────────────────────────┤
│  P/Invoke (NativeMethods.cs)                │
├─────────────────────────────────────────────┤
│  tealeaf_ffi.dll / .so / .dylib (Rust)      │
└─────────────────────────────────────────────┘

Installation

dotnet add package TeaLeaf

The single package bundles everything:

ComponentWhat it provides
TeaLeafManaged wrapper types (TLDocument, TLValue, TLReader), reflection serializer
TeaLeaf.AnnotationsAttributes ([TeaLeaf], [TLSkip], etc.) – included as a dependency
TeaLeaf.GeneratorsC# incremental source generator – bundled as an analyzer
Native librariestealeaf_ffi for all supported platforms (win/linux/osx, x64/arm64)

Two Serialization Approaches

Zero-reflection, compile-time code generation:

[TeaLeaf]
public partial class User
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    [TLOptional] public string? Email { get; set; }
}

// Generated methods
string schema = User.GetTeaLeafSchema();
string text = user.ToTeaLeafText();
string json = user.ToTeaLeafJson();
user.CompileToTeaLeaf("user.tlbx");
var loaded = User.FromTeaLeaf(doc);

Requirements:

  • Class must be partial
  • Annotated with [TeaLeaf]
  • Properties must have public getters (and setters for deserialization)

2. Reflection Serializer

For generic types, dynamic scenarios, or types you don’t control:

using var doc = TeaLeafSerializer.ToDocument(user);
string text = TeaLeafSerializer.ToText(user);
string json = TeaLeafSerializer.ToJson(user);
var loaded = TeaLeafSerializer.Deserialize<User>(doc);

Core Types

TLDocument

The in-memory document, wrapping a native handle:

// Parse text
using var doc = TLDocument.Parse("name: alice\nage: 30");

// Load from file
using var doc = TLDocument.ParseFile("data.tl");

// From JSON
using var doc = TLDocument.FromJson(jsonString);

// Access values
string[] keys = doc.Keys;
using var value = doc["name"];

// Output
string text = doc.ToText();
string json = doc.ToJson();
doc.Compile("output.tlbx", compress: true);

TLValue

Represents any TeaLeaf value with type-safe accessors:

using var val = doc["users"];

// Type checking
TLType type = val.Type;
bool isNull = val.IsNull;

// Primitive access
bool? b = val.AsBool();
long? i = val.AsInt();
double? f = val.AsFloat();
string? s = val.AsString();
byte[]? bytes = val.AsBytes();
DateTimeOffset? ts = val.AsDateTime();

// Collection access
int len = val.ArrayLength;
using var elem = val[0];
using var field = val["name"];
string[] keys = val.ObjectKeys;

// Dynamic conversion
object? obj = val.ToObject();

TLReader

Binary file reader with optional memory mapping:

// Standard read
using var reader = TLReader.Open("data.tlbx");

// Memory-mapped (zero-copy for large files)
using var reader = TLReader.OpenMmap("data.tlbx");

// Access
string[] keys = reader.Keys;
using var val = reader["users"];

// Schema introspection
int schemaCount = reader.SchemaCount;
string name = reader.GetSchemaName(0);

Next Steps