diff --git a/Cargo.lock b/Cargo.lock index e0770de2..0d7f8209 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2932,6 +2932,9 @@ dependencies = [ [[package]] name = "revolt-result" version = "0.1.0" +dependencies = [ + "serde", +] [[package]] name = "revolt_okapi" diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 839aceec..12947827 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -5,4 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +serde = [ "dep:serde" ] +default = [ "serde" ] + [dependencies] +# Serialisation +serde = { version = "1", features = ["derive"], optional = true } diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index 7d12d9af..7f0eea5d 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -1,14 +1,139 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +#[cfg(feature = "serde")] +#[macro_use] +extern crate serde; + +/// Result type with custom Error +pub type Result = std::result::Result; + +/// Error information +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone)] +pub struct Error { + /// Type of error and additional information + #[cfg_attr(feature = "serde", serde(flatten))] + pub error_type: ErrorType, + + /// Where this error occurred + pub location: String, +} + +/// Possible error types +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +#[derive(Debug, Clone)] +pub enum ErrorType { + /// This error was not labeled :( + LabelMe, + + // ? Onboarding related errors + AlreadyOnboarded, + + // ? User related errors + UsernameTaken, + InvalidUsername, + UnknownUser, + AlreadyFriends, + AlreadySentRequest, + Blocked, + BlockedByOther, + NotFriends, + + // ? Channel related errors + UnknownChannel, + UnknownAttachment, + UnknownMessage, + CannotEditMessage, + CannotJoinCall, + TooManyAttachments { + max: usize, + }, + TooManyReplies { + max: usize, + }, + TooManyChannels { + max: usize, + }, + EmptyMessage, + PayloadTooLarge, + CannotRemoveYourself, + GroupTooLarge { + max: usize, + }, + AlreadyInGroup, + NotInGroup, + + // ? Server related errors + UnknownServer, + InvalidRole, + Banned, + TooManyServers { + max: usize, + }, + TooManyEmoji { + max: usize, + }, + TooManyRoles { + max: usize, + }, + + // ? Bot related errors + ReachedMaximumBots, + IsBot, + BotIsPrivate, + + // ? User safety related errors + CannotReportYourself, + + // ? Permission errors + MissingPermission { + permission: String, + }, + MissingUserPermission { + permission: String, + }, + NotElevated, + NotPrivileged, + CannotGiveMissingPermissions, + NotOwner, + + // ? General errors + DatabaseError { + operation: String, + with: String, + }, + InternalError, + InvalidOperation, + InvalidCredentials, + InvalidProperty, + InvalidSession, + DuplicateNonce, + NotFound, + NoEffect, + FailedValidation { + error: String, + }, + + // ? Legacy errors + VosoUnavailable, +} + +#[macro_export] +macro_rules! create_error { + ( $error:ident ) => { + $crate::Error { + error_type: $crate::ErrorType::$error, + location: format!("{}:{}:{}", file!(), line!(), column!()), + } + }; } #[cfg(test)] mod tests { - use super::*; + use crate::ErrorType; #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); + fn use_macro_to_construct_error() { + let error = create_error!(LabelMe); + assert!(matches!(error.error_type, ErrorType::LabelMe)); } }