Skip to main content

layer_tl_parser/tl/
parameter.rs

1// Copyright (c) Ankit Chaubey <ankitchaubey.dev@gmail.com>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4// NOTE:
5// The "Layer" project is no longer maintained or supported.
6// Its original purpose for personal SDK/APK experimentation and learning
7// has been fulfilled.
8//
9// Please use Ferogram instead:
10// https://github.com/ankit-chaubey/ferogram
11// Ferogram will receive future updates and development, although progress
12// may be slower.
13//
14// Ferogram is an async Telegram MTProto client library written in Rust.
15// Its implementation follows the behaviour of the official Telegram clients,
16// particularly Telegram Desktop and TDLib, and aims to provide a clean and
17// modern async interface for building Telegram clients and tools.
18
19use std::fmt;
20use std::str::FromStr;
21
22use crate::errors::ParamParseError;
23use crate::tl::ParameterType;
24
25/// A single `name:Type` parameter inside a TL definition.
26#[derive(Clone, Debug, PartialEq, Eq, Hash)]
27pub struct Parameter {
28    /// The parameter name as it appears in the TL schema.
29    pub name: String,
30    /// The resolved type of this parameter.
31    pub ty: ParameterType,
32}
33
34impl fmt::Display for Parameter {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        write!(f, "{}:{}", self.name, self.ty)
37    }
38}
39
40impl FromStr for Parameter {
41    type Err = ParamParseError;
42
43    /// Parses a single parameter token such as `flags:#`, `id:long`, or
44    /// `photo:flags.0?InputPhoto`.
45    ///
46    /// Returns `Err(ParamParseError::TypeDef { name })` for the special
47    /// `{X:Type}` generic-parameter-definition syntax so callers can handle it
48    /// without the overhead of `?`.
49    fn from_str(token: &str) -> Result<Self, Self::Err> {
50        // Generic type-definition `{X:Type}`: not a real parameter
51        if let Some(inner) = token.strip_prefix('{') {
52            return Err(match inner.strip_suffix(":Type}") {
53                Some(name) => ParamParseError::TypeDef { name: name.into() },
54                None => ParamParseError::MissingDef,
55            });
56        }
57
58        let (name, ty_str) = token
59            .split_once(':')
60            .ok_or(ParamParseError::NotImplemented)?;
61
62        if name.is_empty() || ty_str.is_empty() {
63            return Err(ParamParseError::Empty);
64        }
65
66        Ok(Self {
67            name: name.to_owned(),
68            ty: ty_str.parse()?,
69        })
70    }
71}