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}