.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:
| Component | What it provides |
|---|---|
TeaLeaf | Managed wrapper types (TLDocument, TLValue, TLReader), reflection serializer |
TeaLeaf.Annotations | Attributes ([TeaLeaf], [TLSkip], etc.) – included as a dependency |
TeaLeaf.Generators | C# incremental source generator – bundled as an analyzer |
| Native libraries | tealeaf_ffi for all supported platforms (win/linux/osx, x64/arm64) |
Two Serialization Approaches
1. Source Generator (Recommended)
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
- Source Generator – compile-time code generation in detail
- Attributes Reference – all available annotations
- Reflection Serializer – runtime serialization
- Native Types –
TLDocument,TLValue,TLReaderAPI - Diagnostics – compiler warnings and errors
- Platform Support – supported runtimes and architectures