forked from loco-rs/loco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoctor.rs
168 lines (156 loc) · 4.95 KB
/
doctor.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
use std::{collections::BTreeMap, process::Command};
use crate::{
boot,
config::{Config, Database},
db, redis, Error, Result,
};
const SEAORM_INSTALLED: &str = "SeaORM CLI is installed";
const SEAORM_NOT_INSTALLED: &str = "SeaORM CLI was not found";
const SEAORM_NOT_FIX: &str = r"To fix, run:
$ cargo install sea-orm-cli";
const DB_CONNECTION_FAILED: &str = "DB connection: fails";
const DB_CONNECTION_SUCCESS: &str = "DB connection: success";
const REDIS_CONNECTION_SUCCESS: &str = "Redis connection: success";
const REDIS_CONNECTION_FAILED: &str = "Redis connection: failed";
const REDIS_CONNECTION_NOT_CONFIGURE: &str = "Redis not configure";
/// Represents different resources that can be checked.
#[derive(PartialOrd, PartialEq, Eq, Ord)]
pub enum Resource {
SeaOrmCLI,
Database,
Redis,
}
/// Represents the status of a resource check.
#[derive(Debug, PartialEq, Eq)]
pub enum CheckStatus {
Ok,
NotOk,
NotConfigure,
}
/// Represents the result of a resource check.
#[derive(Debug)]
pub struct Check {
/// The status of the check.
pub status: CheckStatus,
/// A message describing the result of the check.
pub message: String,
/// Additional information or instructions related to the check.
pub description: Option<String>,
}
impl Check {
#[must_use]
pub fn valid(&self) -> bool {
self.status != CheckStatus::NotOk
}
/// Convert to a Result type
///
/// # Errors
///
/// This function will return an error if Check fails
pub fn to_result(&self) -> Result<()> {
if self.valid() {
Ok(())
} else {
Err(Error::Message(format!(
"{} {}",
self.message,
self.description.clone().unwrap_or_default()
)))
}
}
}
impl std::fmt::Display for Check {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let icon = match self.status {
CheckStatus::Ok => "✅",
CheckStatus::NotOk => "❌",
CheckStatus::NotConfigure => "⚠️ ",
};
write!(
f,
"{} {}{}",
icon,
self.message,
self.description
.as_ref()
.map(|d| format!("\n{d}"))
.unwrap_or_default()
)
}
}
/// Runs checks for all configured resources.
pub async fn run_all(config: &Config) -> BTreeMap<Resource, Check> {
BTreeMap::from([
(Resource::SeaOrmCLI, check_seaorm_cli()),
(Resource::Database, check_db(&config.database).await),
(Resource::Redis, check_redis(config).await),
])
}
/// Checks the database connection.
pub async fn check_db(config: &Database) -> Check {
match db::connect(config).await {
Ok(conn) => match conn.ping().await {
Ok(()) => match db::verify_access(&conn).await {
Ok(()) => Check {
status: CheckStatus::Ok,
message: DB_CONNECTION_SUCCESS.to_string(),
description: None,
},
Err(err) => Check {
status: CheckStatus::NotOk,
message: DB_CONNECTION_FAILED.to_string(),
description: Some(err.to_string()),
},
},
Err(err) => Check {
status: CheckStatus::NotOk,
message: DB_CONNECTION_FAILED.to_string(),
description: Some(err.to_string()),
},
},
Err(err) => Check {
status: CheckStatus::NotOk,
message: DB_CONNECTION_FAILED.to_string(),
description: Some(err.to_string()),
},
}
}
/// Checks the Redis connection.
pub async fn check_redis(config: &Config) -> Check {
if let Some(conn) = boot::connect_redis(config).await {
match redis::ping(&conn).await {
Ok(()) => Check {
status: CheckStatus::Ok,
message: REDIS_CONNECTION_SUCCESS.to_string(),
description: None,
},
Err(err) => Check {
status: CheckStatus::NotOk,
message: REDIS_CONNECTION_FAILED.to_string(),
description: Some(err.to_string()),
},
}
} else {
Check {
status: CheckStatus::NotConfigure,
message: REDIS_CONNECTION_NOT_CONFIGURE.to_string(),
description: None,
}
}
}
/// Checks the presence and version of `SeaORM` CLI.
#[must_use]
pub fn check_seaorm_cli() -> Check {
match Command::new("sea-orm-cli").arg("--version").output() {
Ok(_) => Check {
status: CheckStatus::Ok,
message: SEAORM_INSTALLED.to_string(),
description: None,
},
Err(_) => Check {
status: CheckStatus::NotOk,
message: SEAORM_NOT_INSTALLED.to_string(),
description: Some(SEAORM_NOT_FIX.to_string()),
},
}
}