1
use std::collections::BTreeMap;
2

            
3
use serde::{Deserialize, Serialize};
4
use serde_json::json;
5
use thiserror::Error;
6

            
7
use crate::core::{
8
    protocol::request_validation::ValidationError,
9
    types::{DbOrUser, MySQLUser},
10
};
11

            
12
pub type UnlockUsersRequest = Vec<MySQLUser>;
13

            
14
pub type UnlockUsersResponse = BTreeMap<MySQLUser, Result<(), UnlockUserError>>;
15

            
16
#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
17
pub enum UnlockUserError {
18
    #[error("Validation error: {0}")]
19
    ValidationError(#[from] ValidationError),
20

            
21
    #[error("User does not exist")]
22
    UserDoesNotExist,
23

            
24
    #[error("User is already unlocked")]
25
    UserIsAlreadyUnlocked,
26

            
27
    #[error("MySQL error: {0}")]
28
    MySqlError(String),
29
}
30

            
31
pub fn print_unlock_users_output_status(output: &UnlockUsersResponse) {
32
    for (username, result) in output {
33
        match result {
34
            Ok(()) => {
35
                println!("User '{username}' unlocked successfully.");
36
            }
37
            Err(err) => {
38
                eprintln!("{}", err.to_error_message(username));
39
                eprintln!("Skipping...");
40
            }
41
        }
42
        println!();
43
    }
44
}
45

            
46
pub fn print_unlock_users_output_status_json(output: &UnlockUsersResponse) {
47
    let value = output
48
        .iter()
49
        .map(|(name, result)| match result {
50
            Ok(()) => (name.to_string(), json!({ "status": "success" })),
51
            Err(err) => (
52
                name.to_string(),
53
                json!({
54
                  "status": "error",
55
                  "type": err.error_type(),
56
                  "error": err.to_error_message(name),
57
                }),
58
            ),
59
        })
60
        .collect::<serde_json::Map<_, _>>();
61
    println!(
62
        "{}",
63
        serde_json::to_string_pretty(&value)
64
            .unwrap_or("Failed to serialize result to JSON".to_string())
65
    );
66
}
67

            
68
impl UnlockUserError {
69
    #[must_use]
70
    pub fn to_error_message(&self, username: &MySQLUser) -> String {
71
        match self {
72
            UnlockUserError::ValidationError(err) => {
73
                err.to_error_message(&DbOrUser::User(username.clone()))
74
            }
75
            UnlockUserError::UserDoesNotExist => {
76
                format!("User '{username}' does not exist.")
77
            }
78
            UnlockUserError::UserIsAlreadyUnlocked => {
79
                format!("User '{username}' is already unlocked.")
80
            }
81
            UnlockUserError::MySqlError(err) => {
82
                format!("MySQL error: {err}")
83
            }
84
        }
85
    }
86

            
87
    #[must_use]
88
    pub fn error_type(&self) -> String {
89
        match self {
90
            UnlockUserError::ValidationError(err) => err.error_type(),
91
            UnlockUserError::UserDoesNotExist => "user-does-not-exist".to_string(),
92
            UnlockUserError::UserIsAlreadyUnlocked => "user-is-already-unlocked".to_string(),
93
            UnlockUserError::MySqlError(_) => "mysql-error".to_string(),
94
        }
95
    }
96
}