ferogram-tl-parser 0.6.5

Parser for Telegram's Type Language (.tl) schema files
Documentation
/*
 * Copyright (c) 2026 Ankit Chaubey <ankitchaubey.dev@gmail.com>
 * https://github.com/ankit-chaubey
 *
 * Project: ferogram
 * Website: https://ferogram.dev
 *
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
 * This file may not be copied, modified, or distributed except according
 * to those terms.
 */

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

#[test]
fn parses_simple_type() {
    let src = "boolFalse#bc799737 = Bool;";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 1);
    assert_eq!(defs[0].name, "boolFalse");
    assert_eq!(defs[0].id, 0xbc799737);
    assert_eq!(defs[0].ty.name, "Bool");
}

#[test]
fn parses_function_category() {
    let src = "
---functions---
help.getConfig#c4f9186b = Config;
";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 1);
    assert_eq!(defs[0].category, Category::Functions);
    assert_eq!(defs[0].name, "getConfig");
    assert_eq!(defs[0].namespace, vec!["help"]);
}

#[test]
fn parses_flagged_parameter() {
    let src = "user#3ff6ecb0 flags:# id:long username:flags.0?string = User;";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 1);
    assert_eq!(defs[0].params.len(), 3); // flags, id, username
}

#[test]
fn skips_blank_lines_and_comments() {
    let src = "
// this is a comment
boolTrue#997275b5 = Bool;
// another comment

boolFalse#bc799737 = Bool;
";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 2);
}

#[test]
fn crc32_derived_id() {
    // boolFalse#bc799737: omit #id, parser must derive same value via CRC32
    let src = "boolFalse = Bool;";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs[0].id, 0xbc799737);
}

#[test]
fn inline_comment_stripped() {
    let src = "boolFalse#bc799737 = Bool; // trailing comment";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 1);
    assert_eq!(defs[0].name, "boolFalse");
}

#[test]
fn multi_defs_one_line() {
    let src = "boolTrue#997275b5 = Bool; boolFalse#bc799737 = Bool;";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 2);
    assert_eq!(defs[0].name, "boolTrue");
    assert_eq!(defs[1].name, "boolFalse");
}

#[test]
fn missing_final_semicolon() {
    let src = "boolFalse#bc799737 = Bool";
    let defs: Vec<_> = parse_tl_file(src).collect::<Result<_, _>>().unwrap();
    assert_eq!(defs.len(), 1);
    assert_eq!(defs[0].name, "boolFalse");
}