Skip to main content

rustauth_plugins/anonymous/
errors.rs

1use http::StatusCode;
2use rustauth_core::api::{ApiErrorResponse, ApiResponse};
3use rustauth_core::error::RustAuthError;
4use rustauth_core::error_codes::ErrorCode;
5use rustauth_core::plugin::PluginErrorCode;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum AnonymousError {
9    InvalidEmailFormat,
10    FailedToCreateUser,
11    CouldNotCreateSession,
12    AnonymousUsersCannotSignInAgainAnonymously,
13    FailedToDeleteAnonymousUser,
14    UserIsNotAnonymous,
15    DeleteAnonymousUserDisabled,
16}
17
18pub const ANONYMOUS_ERROR_CODES: &[(&str, &str)] = &[
19    (
20        "INVALID_EMAIL_FORMAT",
21        "Email was not generated in a valid format",
22    ),
23    ("FAILED_TO_CREATE_USER", "Failed to create user"),
24    ("COULD_NOT_CREATE_SESSION", "Could not create session"),
25    (
26        "ANONYMOUS_USERS_CANNOT_SIGN_IN_AGAIN_ANONYMOUSLY",
27        "Anonymous users cannot sign in again anonymously",
28    ),
29    (
30        "FAILED_TO_DELETE_ANONYMOUS_USER",
31        "Failed to delete anonymous user",
32    ),
33    ("USER_IS_NOT_ANONYMOUS", "User is not anonymous"),
34    (
35        "DELETE_ANONYMOUS_USER_DISABLED",
36        "Deleting anonymous users is disabled",
37    ),
38];
39
40impl AnonymousError {
41    pub fn code(self) -> &'static str {
42        match self {
43            Self::InvalidEmailFormat => "INVALID_EMAIL_FORMAT",
44            Self::FailedToCreateUser => "FAILED_TO_CREATE_USER",
45            Self::CouldNotCreateSession => "COULD_NOT_CREATE_SESSION",
46            Self::AnonymousUsersCannotSignInAgainAnonymously => {
47                "ANONYMOUS_USERS_CANNOT_SIGN_IN_AGAIN_ANONYMOUSLY"
48            }
49            Self::FailedToDeleteAnonymousUser => "FAILED_TO_DELETE_ANONYMOUS_USER",
50            Self::UserIsNotAnonymous => "USER_IS_NOT_ANONYMOUS",
51            Self::DeleteAnonymousUserDisabled => "DELETE_ANONYMOUS_USER_DISABLED",
52        }
53    }
54
55    pub fn message(self) -> &'static str {
56        ANONYMOUS_ERROR_CODES
57            .iter()
58            .find_map(|(code, message)| (*code == self.code()).then_some(*message))
59            .unwrap_or("Anonymous plugin error")
60    }
61}
62
63impl ErrorCode for AnonymousError {
64    fn as_str(&self) -> &str {
65        (*self).code()
66    }
67
68    fn message(&self) -> &str {
69        (*self).message()
70    }
71}
72
73pub fn error_codes() -> Vec<PluginErrorCode> {
74    ANONYMOUS_ERROR_CODES
75        .iter()
76        .map(|(code, message)| PluginErrorCode::new(*code, *message))
77        .collect()
78}
79
80pub fn error_response(
81    status: StatusCode,
82    error: AnonymousError,
83) -> Result<ApiResponse, RustAuthError> {
84    let body = serde_json::to_vec(&ApiErrorResponse::from_error_code(error))
85        .map_err(|err| RustAuthError::Api(err.to_string()))?;
86
87    http::Response::builder()
88        .status(status)
89        .header(http::header::CONTENT_TYPE, "application/json")
90        .body(body)
91        .map_err(|err| RustAuthError::Api(err.to_string()))
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97    use rustauth_core::error_codes::ErrorCode;
98
99    fn assert_error_code(code: impl ErrorCode, expected_code: &str, expected_message: &str) {
100        assert_eq!(code.as_str(), expected_code);
101        assert_eq!(code.message(), expected_message);
102    }
103
104    #[test]
105    fn anonymous_error_implements_error_code_trait() {
106        assert_error_code(
107            AnonymousError::InvalidEmailFormat,
108            "INVALID_EMAIL_FORMAT",
109            "Email was not generated in a valid format",
110        );
111    }
112}