Skip to main content

ferogram_tl_parser/
errors.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::num::ParseIntError;
14
15/// Errors produced while parsing a single parameter token.
16#[derive(Clone, Debug, PartialEq)]
17pub enum ParamParseError {
18    /// An empty string was encountered where a name/type was expected.
19    Empty,
20    /// A `{X:Type}` generic type definition (not a real error; used as a signal).
21    TypeDef {
22        /// The name of the generic type parameter (e.g. `"X"` from `{X:Type}`).
23        name: String,
24    },
25    /// A `{...}` block that isn't a valid type definition.
26    MissingDef,
27    /// A flag expression (`name.N?Type`) was malformed.
28    InvalidFlag,
29    /// A generic `<...>` argument was malformed (missing closing `>`).
30    InvalidGeneric,
31    /// A bare `name` with no `:type`: e.g. old-style `? = Int`.
32    NotImplemented,
33}
34
35impl fmt::Display for ParamParseError {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::Empty => write!(f, "empty token"),
39            Self::TypeDef { name } => write!(f, "generic type definition: {name}"),
40            Self::MissingDef => write!(f, "unknown generic or flag definition"),
41            Self::InvalidFlag => write!(f, "invalid flag expression"),
42            Self::InvalidGeneric => write!(f, "invalid generic argument (unclosed `<`)"),
43            Self::NotImplemented => write!(f, "parameter without `:type` is not supported"),
44        }
45    }
46}
47
48impl std::error::Error for ParamParseError {}
49
50/// Errors produced while parsing a complete TL definition.
51#[derive(Debug, PartialEq)]
52pub enum ParseError {
53    /// The input was blank.
54    Empty,
55    /// No `= Type` was found.
56    MissingType,
57    /// The name (before `=`) was missing or had empty namespace components.
58    MissingName,
59    /// The `#id` hex literal was unparseable.
60    InvalidId(ParseIntError),
61    /// A parameter was invalid.
62    InvalidParam(ParamParseError),
63    /// The definition uses a syntax we don't support yet.
64    NotImplemented,
65}
66
67impl fmt::Display for ParseError {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        match self {
70            Self::Empty => write!(f, "empty definition"),
71            Self::MissingType => write!(f, "missing `= Type`"),
72            Self::MissingName => write!(f, "missing or malformed name"),
73            Self::InvalidId(e) => write!(f, "invalid constructor ID: {e}"),
74            Self::InvalidParam(e) => write!(f, "invalid parameter: {e}"),
75            Self::NotImplemented => write!(f, "unsupported TL syntax"),
76        }
77    }
78}
79
80impl std::error::Error for ParseError {
81    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
82        match self {
83            Self::InvalidId(e) => Some(e),
84            Self::InvalidParam(e) => Some(e),
85            _ => None,
86        }
87    }
88}