Skip to main content

layer_tl_parser/tl/
parameter.rs

1use std::fmt;
2use std::str::FromStr;
3
4use crate::errors::ParamParseError;
5use crate::tl::ParameterType;
6
7/// A single `name:Type` parameter inside a TL definition.
8#[derive(Clone, Debug, PartialEq, Eq, Hash)]
9pub struct Parameter {
10    /// The parameter name as it appears in the TL schema.
11    pub name: String,
12    /// The resolved type of this parameter.
13    pub ty: ParameterType,
14}
15
16impl fmt::Display for Parameter {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        write!(f, "{}:{}", self.name, self.ty)
19    }
20}
21
22impl FromStr for Parameter {
23    type Err = ParamParseError;
24
25    /// Parses a single parameter token such as `flags:#`, `id:long`, or
26    /// `photo:flags.0?InputPhoto`.
27    ///
28    /// Returns `Err(ParamParseError::TypeDef { name })` for the special
29    /// `{X:Type}` generic-parameter-definition syntax so callers can handle it
30    /// without the overhead of `?`.
31    fn from_str(token: &str) -> Result<Self, Self::Err> {
32        // Generic type-definition `{X:Type}` — not a real parameter
33        if let Some(inner) = token.strip_prefix('{') {
34            return Err(match inner.strip_suffix(":Type}") {
35                Some(name) => ParamParseError::TypeDef { name: name.into() },
36                None => ParamParseError::MissingDef,
37            });
38        }
39
40        let (name, ty_str) = token.split_once(':').ok_or(ParamParseError::NotImplemented)?;
41
42        if name.is_empty() || ty_str.is_empty() {
43            return Err(ParamParseError::Empty);
44        }
45
46        Ok(Self {
47            name: name.to_owned(),
48            ty: ty_str.parse()?,
49        })
50    }
51}