layer-tl-parser 0.4.6

Parser for Telegram's Type Language (.tl) schema files
Documentation

๐Ÿ” layer-tl-parser

A parser for Telegram's TL (Type Language) schema files.

Crates.io docs.rs License: MIT OR Apache-2.0 Rust

Turns raw .tl schema text into a structured AST โ€” the foundation of the entire type system.


๐Ÿ“ฆ Installation

[dependencies]
layer-tl-parser = "0.4.6"

Note: Most users don't depend on this crate directly. It is used internally by layer-tl-gen (as a build-dependency) which in turn is used by layer-tl-types to generate all Telegram API types at build time.


โœจ What It Does

The Telegram API is defined in a custom schema language called TL (Type Language). Every type, constructor, and function in the Telegram protocol is described in .tl files โ€” api.tl for the high-level API, mtproto.tl for the low-level MTProto protocol.

layer-tl-parser reads these schema files and produces a structured AST that can be consumed by code generators (like layer-tl-gen) to produce native Rust types.


๐Ÿ“ TL Schema Format

A .tl file looks like this:

// A constructor (type definition)
message#9cb490e9 flags:# out:flags.1?true id:int peer_id:Peer message:string = Message;

// A function (RPC call)
messages.sendMessage#545cd15a peer:InputPeer message:string random_id:long = Updates;

// An abstract type with multiple constructors
inputPeerEmpty#7f3b18ea = InputPeer;
inputPeerSelf#7da07ec9 = InputPeer;
inputPeerUser#dde8a54c user_id:long access_hash:long = InputPeer;

layer-tl-parser parses all of this into typed Rust structures.


๐Ÿ—๏ธ AST Structure

/// A single parsed TL definition (constructor or function)
pub struct Definition {
    pub name:     String,         // e.g. "message"
    pub id:       Option<u32>,    // e.g. 0x9cb490e9 (CRC32, may be omitted)
    pub params:   Vec<Parameter>, // field definitions
    pub ty:       Type,           // return type / abstract type name
    pub category: Category,       // Type or Function
}

pub struct Parameter {
    pub name: String,
    pub ty:   ParameterType,
}

/// Parameter types cover: bare, boxed, flags field, conditional, repeated
pub enum ParameterType {
    /// A `flags:#` field โ€” holds the bitfield for conditional parameters
    Flags,
    /// A normal or conditional parameter
    Normal {
        ty:   Type,
        flag: Option<Flag>,   // present if this field is conditional (flags.N?type)
    },
    /// A repeated block (rare, used in some MTProto types)
    Repeated {
        params: Vec<Parameter>,
    },
}

pub enum Category {
    /// This definition is a TL constructor (contributes to an abstract type)
    Type,
    /// This definition is a TL function (an RPC call)
    Function,
}

๐Ÿ’ก Usage

use layer_tl_parser::{parse_tl_file, tl::Category};

let schema = std::fs::read_to_string("api.tl").unwrap();
let definitions = parse_tl_file(&schema).unwrap();

for def in &definitions {
    match def.category {
        Category::Type => {
            println!("Constructor: {} โ†’ {}", def.name, def.ty.name);
        }
        Category::Function => {
            println!("Function:    {} (returns {})", def.name, def.ty.name);
        }
    }
}

let types_count = definitions.iter().filter(|d| d.category == Category::Type).count();
let fns_count   = definitions.iter().filter(|d| d.category == Category::Function).count();
println!("{} constructors, {} functions", types_count, fns_count);

๐Ÿ”„ How the Iterator Works

The parser exposes a streaming iterator (TlIterator) over definitions, not a batch parse. This lets the code generator process one definition at a time without holding the full AST in memory.

parse_tl_file() collects the iterator into a Vec<Definition> for convenience. If you need streaming, use the iterator directly:

use layer_tl_parser::TlIterator;

let schema = std::fs::read_to_string("api.tl").unwrap();
for def in TlIterator::new(&schema) {
    // process each definition as it is parsed
}

โš ๏ธ Error Handling

Parse errors are returned as layer_tl_parser::ParseError with the line content that failed to parse. Unknown or malformed tokens cause the iterator to stop and return an error rather than silently skipping.


๐Ÿ”— Part of the layer stack

layer-tl-types  (generated types, user-facing)
โ””โ”€โ”€ layer-tl-gen    (code generator, build-time)
    โ””โ”€โ”€ layer-tl-parser    โ† you are here

๐Ÿ“„ License

Licensed under either of, at your option:


๐Ÿ‘ค Author

Ankit Chaubey
github.com/ankit-chaubey ยท ankitchaubey.in ยท ankitchaubey.dev@gmail.com

๐Ÿ“ฆ github.com/ankit-chaubey/layer