smbcloud_model/
error_codes.rs

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