onechatsocial_result/
lib.rs

1#[cfg(feature = "serde")]
2#[macro_use]
3extern crate serde;
4
5#[cfg(feature = "schemas")]
6#[macro_use]
7extern crate schemars;
8
9#[cfg(feature = "rocket")]
10pub mod rocket;
11
12#[cfg(feature = "okapi")]
13pub mod okapi;
14
15/// Result type with custom Error
16pub type Result<T, E = Error> = std::result::Result<T, E>;
17
18/// Error information
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20#[cfg_attr(feature = "schemas", derive(JsonSchema))]
21#[derive(Debug, Clone)]
22pub struct Error {
23    /// Type of error and additional information
24    #[cfg_attr(feature = "serde", serde(flatten))]
25    pub error_type: ErrorType,
26
27    /// Where this error occurred
28    pub location: String,
29}
30
31/// Possible error types
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[cfg_attr(feature = "serde", serde(tag = "type"))]
34#[cfg_attr(feature = "schemas", derive(JsonSchema))]
35#[derive(Debug, Clone)]
36pub enum ErrorType {
37    /// This error was not labeled :(
38    LabelMe,
39
40    // ? Onboarding related errors
41    AlreadyOnboarded,
42
43    // ? User related errors
44    UsernameTaken,
45    InvalidUsername,
46    DiscriminatorChangeRatelimited,
47    UnknownUser,
48    AlreadyFriends,
49    AlreadySentRequest,
50    Blocked,
51    BlockedByOther,
52    NotFriends,
53
54    // ? Channel related errors
55    UnknownChannel,
56    UnknownAttachment,
57    UnknownMessage,
58    CannotEditMessage,
59    CannotJoinCall,
60    TooManyAttachments {
61        max: usize,
62    },
63    TooManyEmbeds {
64        max: usize,
65    },
66    TooManyReplies {
67        max: usize,
68    },
69    TooManyChannels {
70        max: usize,
71    },
72    EmptyMessage,
73    PayloadTooLarge,
74    CannotRemoveYourself,
75    GroupTooLarge {
76        max: usize,
77    },
78    AlreadyInGroup,
79    NotInGroup,
80
81    // ? Server related errors
82    UnknownServer,
83    InvalidRole,
84    Banned,
85    TooManyServers {
86        max: usize,
87    },
88    TooManyEmoji {
89        max: usize,
90    },
91    TooManyRoles {
92        max: usize,
93    },
94    AlreadyInServer,
95
96    // ? Bot related errors
97    ReachedMaximumBots,
98    IsBot,
99    BotIsPrivate,
100
101    // ? User safety related errors
102    CannotReportYourself,
103
104    // ? Permission errors
105    MissingPermission {
106        permission: String,
107    },
108    MissingUserPermission {
109        permission: String,
110    },
111    NotElevated,
112    NotPrivileged,
113    CannotGiveMissingPermissions,
114    NotOwner,
115
116    // ? General errors
117    DatabaseError {
118        operation: String,
119        collection: String,
120    },
121    InternalError,
122    InvalidOperation,
123    InvalidCredentials,
124    InvalidProperty,
125    InvalidSession,
126    DuplicateNonce,
127    NotFound,
128    NoEffect,
129    FailedValidation {
130        error: String,
131    },
132
133    // ? Legacy errors
134    VosoUnavailable,
135}
136
137#[macro_export]
138macro_rules! create_error {
139    ( $error: ident $( $tt:tt )? ) => {
140        $crate::Error {
141            error_type: $crate::ErrorType::$error $( $tt )?,
142            location: format!("{}:{}:{}", file!(), line!(), column!()),
143        }
144    };
145}
146
147#[macro_export]
148macro_rules! create_database_error {
149    ( $operation: expr, $collection: expr ) => {
150        create_error!(DatabaseError {
151            operation: $operation.to_string(),
152            collection: $collection.to_string()
153        })
154    };
155}
156
157#[macro_export]
158#[cfg(debug_assertions)]
159macro_rules! query {
160    ( $self: ident, $type: ident, $collection: expr, $($rest:expr),+ ) => {
161        Ok($self.$type($collection, $($rest),+).await.unwrap())
162    };
163}
164
165#[macro_export]
166#[cfg(not(debug_assertions))]
167macro_rules! query {
168    ( $self: ident, $type: ident, $collection: expr, $($rest:expr),+ ) => {
169        $self.$type($collection, $($rest),+).await
170            .map_err(|_| create_database_error!(stringify!($type), $collection))
171    };
172}
173
174#[cfg(test)]
175mod tests {
176    use crate::ErrorType;
177
178    #[test]
179    fn use_macro_to_construct_error() {
180        let error = create_error!(LabelMe);
181        assert!(matches!(error.error_type, ErrorType::LabelMe));
182    }
183
184    #[test]
185    fn use_macro_to_construct_complex_error() {
186        let error = create_error!(LabelMe);
187        assert!(matches!(error.error_type, ErrorType::LabelMe));
188    }
189}