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