Skip to main content

ferogram_tl_parser/tl/
parameter.rs

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