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