Skip to main content

ferogram_tl_parser/tl/
parameter.rs

1/*
2 * Copyright (c) 2026 Ankit Chaubey <ankitchaubey.dev@gmail.com>
3 * https://github.com/ankit-chaubey
4 *
5 * Project: ferogram
6 * Website: https://ferogram.dev
7 *
8 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
9 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
10 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
11 * This file may not be copied, modified, or distributed except according
12 * to those terms.
13 */
14
15use std::fmt;
16use std::str::FromStr;
17
18use crate::errors::ParamParseError;
19use crate::tl::ParameterType;
20
21/// A single `name:Type` parameter inside a TL definition.
22#[derive(Clone, Debug, PartialEq, Eq, Hash)]
23pub struct Parameter {
24    /// The parameter name as it appears in the TL schema.
25    pub name: String,
26    /// The resolved type of this parameter.
27    pub ty: ParameterType,
28}
29
30impl fmt::Display for Parameter {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        write!(f, "{}:{}", self.name, self.ty)
33    }
34}
35
36impl FromStr for Parameter {
37    type Err = ParamParseError;
38
39    /// Parses a single parameter token such as `flags:#`, `id:long`, or
40    /// `photo:flags.0?InputPhoto`.
41    ///
42    /// Returns `Err(ParamParseError::TypeDef { name })` for the special
43    /// `{X:Type}` generic-parameter-definition syntax so callers can handle it
44    /// without the overhead of `?`.
45    fn from_str(token: &str) -> Result<Self, Self::Err> {
46        // Generic type-definition `{X:Type}`: not a real parameter
47        if let Some(inner) = token.strip_prefix('{') {
48            return Err(match inner.strip_suffix(":Type}") {
49                Some(name) => ParamParseError::TypeDef { name: name.into() },
50                None => ParamParseError::MissingDef,
51            });
52        }
53
54        let (name, ty_str) = token
55            .split_once(':')
56            .ok_or(ParamParseError::NotImplemented)?;
57
58        if name.is_empty() || ty_str.is_empty() {
59            return Err(ParamParseError::Empty);
60        }
61
62        Ok(Self {
63            name: name.to_owned(),
64            ty: ty_str.parse()?,
65        })
66    }
67}