smbcloud_model/
error_codes.rs

1use {
2    core::fmt,
3    log::debug,
4    serde::{Deserialize, Serialize},
5    serde_repr::{Deserialize_repr, Serialize_repr},
6    std::fmt::{Display, Formatter},
7    strum_macros::{EnumIter, IntoStaticStr},
8    thiserror::Error,
9};
10
11#[derive(Error, Serialize, Deserialize, Debug)]
12#[serde(untagged)]
13pub enum ErrorResponse {
14    Error {
15        error_code: ErrorCode,
16        message: String,
17    },
18}
19
20impl Display for ErrorResponse {
21    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22        write!(f, "{:?}", self)
23    }
24}
25
26#[derive(Error, Serialize_repr, Deserialize_repr, Debug, EnumIter, IntoStaticStr)]
27#[repr(i32)]
28pub enum ErrorCode {
29    // Generic errors
30    #[error("Unknown error.")]
31    Unknown = 0,
32    #[error("Parse error.")]
33    ParseError = 1,
34    #[error("Network error. Please check your internet connection and try again.")]
35    NetworkError = 2,
36    #[error("Input error")]
37    InputError = 3,
38    #[error("Missing config file. Please regenerate with 'smb init'.")]
39    MissingConfig = 4,
40    // #[error("Missing id in repository. Please regenerate with 'smb init'.")]
41    // MissingId,
42    #[error("Cancel operation.")]
43    Cancel = 5,
44    // Account
45    #[error("Unauthorized access.")]
46    Unauthorized = 100,
47    #[error("Email already exists.")]
48    EmailAlreadyExist = 1005,
49    // Projects
50    #[error("Project not found.")]
51    ProjectNotFound = 1000,
52    #[error("Runner not supported.")]
53    UnsupportedRunner = 1001,
54}
55
56impl ErrorCode {
57    /// Cannot expose the ErrorCode enum directly to Ruby,
58    /// so we need to get it from i32.
59    pub fn from_i32(value: i32) -> Self {
60        match value {
61            // Account
62            100 => ErrorCode::Unauthorized,
63            1005 => ErrorCode::EmailAlreadyExist,
64            // Projects
65            1000 => ErrorCode::ProjectNotFound,
66            // Generic errors
67            5 => ErrorCode::Cancel,
68            4 => ErrorCode::MissingConfig,
69            3 => ErrorCode::InputError,
70            2 => ErrorCode::ParseError,
71            1 => ErrorCode::NetworkError,
72            // Fallback
73            _ => ErrorCode::Unknown,
74        }
75    }
76
77    // This could be better.
78    pub fn message(&self, l: Option<String>) -> &str {
79        debug!("Language code: {:?}, {}", l, self);
80        match self {
81            ErrorCode::Unknown => "Unknown error.",
82            ErrorCode::ProjectNotFound => "Project not found.",
83            ErrorCode::ParseError => "Parse error.",
84            ErrorCode::NetworkError => {
85                "Network error. Please check your internet connection and try again."
86            }
87            // Accounts
88            ErrorCode::Unauthorized => "Unauthorized access.",
89            ErrorCode::EmailAlreadyExist => "Email already exists.",
90
91            ErrorCode::InputError => "Input error.",
92            ErrorCode::MissingConfig => "Missing config.",
93            ErrorCode::Cancel => "Cancelled operation.",
94            // Projects
95            ErrorCode::UnsupportedRunner => "Unsupported runner.",
96        }
97    }
98
99    pub fn rb_constant_name(&self) -> String {
100        // Using IntoStaticStr to get the variant name directly.
101        // self.into() will return a &'static str representing the variant name.
102        let variant_name_static_str: &'static str = self.into();
103        variant_name_static_str.to_string()
104    }
105}