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    // Generic errors
28    #[error("Unknown error.")]
29    Unknown = 0,
30    #[error("Parse error.")]
31    ParseError = 1,
32    #[error("Network error.")]
33    NetworkError = 2,
34    #[error("Input error")]
35    InputError = 3,
36    #[error("Missing config file. Please regenerate with 'smb init'.")]
37    MissingConfig = 4,
38    // #[error("Missing id in repository. Please regenerate with 'smb init'.")]
39    // MissingId,
40    #[error("Cancel operation.")]
41    Cancel = 5,
42    // Account
43    #[error("Unauthorized access.")]
44    Unauthorized = 100,
45    // Projects
46    #[error("Project not found.")]
47    ProjectNotFound = 1000,
48}
49
50impl ErrorCode {
51    /// Cannot expose the ErrorCode enum directly to Ruby,
52    /// so we need to get it from i32.
53    pub fn from_i32(value: i32) -> Self {
54        match value {
55            // Account
56            100 => ErrorCode::Unauthorized,
57            // Projects
58            1000 => ErrorCode::ProjectNotFound,
59            // Generic errors
60            5 => ErrorCode::Cancel,
61            4 => ErrorCode::MissingConfig,
62            3 => ErrorCode::InputError,
63            2 => ErrorCode::ParseError,
64            1 => ErrorCode::NetworkError,
65            // Fallback
66            _ => ErrorCode::Unknown,
67        }
68    }
69
70    // This could be better.
71    pub fn message(&self, l: Option<String>) -> &str {
72        debug!("Language code: {:?}, {}", l, self);
73        match self {
74            ErrorCode::Unknown => "Unknown error.",
75            ErrorCode::ProjectNotFound => "Project not found.",
76            ErrorCode::ParseError => "Parse error.",
77            ErrorCode::NetworkError => "Network error.",
78            ErrorCode::Unauthorized => "Unauthorized access.",
79            ErrorCode::InputError => "Input error.",
80            ErrorCode::MissingConfig => "Missing config.",
81            ErrorCode::Cancel => "Cancelled operation.",
82        }
83    }
84
85    pub fn rb_constant_name(&self) -> String {
86        // Using IntoStaticStr to get the variant name directly.
87        // self.into() will return a &'static str representing the variant name.
88        let variant_name_static_str: &'static str = self.into();
89        variant_name_static_str.to_string()
90    }
91}