smbcloud_model/
error_codes.rs

1use core::fmt;
2use serde::{Deserialize, Serialize};
3use serde_repr::{Deserialize_repr, Serialize_repr};
4use std::fmt::{Display, Formatter};
5use strum_macros::{EnumIter, IntoStaticStr};
6use thiserror::Error;
7
8#[derive(Error, Serialize, Deserialize, Debug)]
9#[serde(untagged)]
10pub enum ErrorResponse {
11    Error {
12        error_code: ErrorCode,
13        message: String,
14    },
15}
16
17impl Display for ErrorResponse {
18    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
19        write!(f, "{:?}", self)
20    }
21}
22
23#[derive(Error, Serialize_repr, Deserialize_repr, Debug, EnumIter, IntoStaticStr)]
24#[repr(i32)]
25pub enum ErrorCode {
26    #[error("Unknown error.")]
27    Unknown = 0,
28    #[error("Parse error.")]
29    ParseError = 1,
30    #[error("Network error.")]
31    NetworkError = 2,
32    // Account
33    #[error("Unauthorized access.")]
34    Unauthorized = 100,
35    // Projects
36    #[error("Project not found.")]
37    ProjectNotFound = 1000,
38}
39
40impl ErrorCode {
41    /// Cannot expose the ErrorCode enum directly to Ruby,
42    /// so we need to get it from i32.
43    pub fn from_i32(value: i32) -> Self {
44        match value {
45            // Account
46            100 => ErrorCode::Unauthorized,
47            // Projects
48            1000 => ErrorCode::ProjectNotFound,
49            // Fallback
50            2 => ErrorCode::ParseError,
51            1 => ErrorCode::NetworkError,
52            _ => ErrorCode::Unknown,
53        }
54    }
55
56    // This could be better.
57    pub fn message(&self, l: Option<String>) -> &str {
58        print!("Language code: {:?}, {}", l, self);
59        match self {
60            ErrorCode::Unknown => "Unknown error.",
61            ErrorCode::ProjectNotFound => "Project not found.",
62            ErrorCode::ParseError => "Parse error.",
63            ErrorCode::NetworkError => "Network error.",
64            ErrorCode::Unauthorized => "Unauthorized access.",
65        }
66    }
67
68    pub fn rb_constant_name(&self) -> String {
69        // Using IntoStaticStr to get the variant name directly.
70        // self.into() will return a &'static str representing the variant name.
71        let variant_name_static_str: &'static str = self.into();
72        variant_name_static_str.to_string()
73    }
74}