1use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, Serialize, Deserialize, Default)]
10#[serde(default)]
11pub struct CoolConfig {
12 pub init_db: bool,
14 pub init_menu: bool,
16 pub init_judge: String,
18 pub eps: bool,
20 pub tenant: Option<TenantConfig>,
22 pub i18n: Option<I18nConfig>,
24 pub crud: CrudConfig,
26 pub file: Option<FileConfig>,
28 pub redis: Option<RedisConfig>,
30 pub jwt: JwtConfig,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, Default)]
36pub struct TenantConfig {
37 pub enable: bool,
39 #[serde(default)]
41 pub urls: Vec<String>,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize, Default)]
46pub struct I18nConfig {
47 pub enable: bool,
49 #[serde(default)]
51 pub languages: Vec<String>,
52 pub service_url: Option<String>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct CrudConfig {
59 #[serde(default = "default_soft_delete")]
61 pub soft_delete: bool,
62 #[serde(default = "default_page_size")]
64 pub page_size: u64,
65 #[serde(default = "default_upsert")]
67 pub upsert: String,
68}
69
70impl Default for CrudConfig {
71 fn default() -> Self {
72 Self {
73 soft_delete: true,
74 page_size: 20,
75 upsert: "normal".to_string(),
76 }
77 }
78}
79
80fn default_soft_delete() -> bool {
81 true
82}
83
84fn default_page_size() -> u64 {
85 20
86}
87
88fn default_upsert() -> String {
89 "normal".to_string()
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct FileConfig {
95 pub mode: String,
97 pub domain: Option<String>,
99 pub oss: Option<OssConfig>,
101 pub cos: Option<CosConfig>,
103 pub qiniu: Option<QiniuConfig>,
105 pub aws: Option<AwsConfig>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct OssConfig {
112 pub access_key_id: String,
113 pub access_key_secret: String,
114 pub bucket: String,
115 pub endpoint: String,
116 pub timeout: Option<String>,
117 pub exp_after: Option<u64>,
118 pub max_size: Option<u64>,
119 pub host: Option<String>,
120 pub public_domain: Option<String>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct CosConfig {
126 pub access_key_id: String,
127 pub access_key_secret: String,
128 pub bucket: String,
129 pub region: String,
130 pub public_domain: String,
131 pub duration_seconds: Option<u64>,
132 pub allow_prefix: Option<String>,
133 pub allow_actions: Option<Vec<String>>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct QiniuConfig {
139 pub access_key_id: String,
140 pub access_key_secret: String,
141 pub bucket: String,
142 pub region: String,
143 pub public_domain: String,
144 pub upload_url: Option<String>,
145 pub file_key: Option<String>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct AwsConfig {
151 pub access_key_id: String,
152 pub secret_access_key: String,
153 pub bucket: String,
154 pub region: String,
155 pub fields: Option<HashMap<String, String>>,
156 pub conditions: Option<Vec<serde_json::Value>>,
157 pub expires: Option<u64>,
158 pub public_domain: Option<String>,
159 pub force_path_style: Option<bool>,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize)]
164pub struct RedisConfig {
165 pub host: String,
166 pub port: u16,
167 pub password: Option<String>,
168 pub db: u8,
169}
170
171impl RedisConfig {
172 pub fn url(&self) -> String {
174 match &self.password {
175 Some(pwd) if !pwd.is_empty() => {
176 format!("redis://:{}@{}:{}/{}", pwd, self.host, self.port, self.db)
177 }
178 _ => format!("redis://{}:{}/{}", self.host, self.port, self.db),
179 }
180 }
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct JwtConfig {
186 #[serde(default = "default_jwt_secret")]
188 pub secret: String,
189 #[serde(default = "default_jwt_expire")]
191 pub expire: u64,
192 #[serde(default = "default_jwt_refresh_expire")]
194 pub refresh_expire: u64,
195}
196
197impl Default for JwtConfig {
198 fn default() -> Self {
199 Self {
200 secret: "cool-admin-rust".to_string(),
201 expire: 7200,
202 refresh_expire: 604800,
203 }
204 }
205}
206
207fn default_jwt_secret() -> String {
208 "cool-admin-rust".to_string()
209}
210
211fn default_jwt_expire() -> u64 {
212 7200
213}
214
215fn default_jwt_refresh_expire() -> u64 {
216 604800
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize, Default)]
221pub struct ModuleConfig {
222 pub name: String,
224 pub description: String,
226 #[serde(default)]
228 pub order: i32,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct DatabaseConfig {
234 pub r#type: String,
236 pub host: Option<String>,
238 pub port: Option<u16>,
240 pub username: Option<String>,
242 pub password: Option<String>,
244 pub database: String,
246 #[serde(default = "default_max_connections")]
248 pub max_connections: u32,
249 #[serde(default = "default_min_connections")]
251 pub min_connections: u32,
252 #[serde(default = "default_connect_timeout")]
254 pub connect_timeout: u64,
255 #[serde(default)]
257 pub logging: bool,
258 #[serde(default)]
260 pub synchronize: bool,
261}
262
263fn default_max_connections() -> u32 {
264 100
265}
266
267fn default_min_connections() -> u32 {
268 5
269}
270
271fn default_connect_timeout() -> u64 {
272 10
273}
274
275impl DatabaseConfig {
276 pub fn url(&self) -> String {
278 match self.r#type.as_str() {
279 "sqlite" => format!("sqlite://{}?mode=rwc", self.database),
280 "mysql" => {
281 format!(
282 "mysql://{}:{}@{}:{}/{}",
283 self.username.as_deref().unwrap_or("root"),
284 self.password.as_deref().unwrap_or(""),
285 self.host.as_deref().unwrap_or("localhost"),
286 self.port.unwrap_or(3306),
287 self.database
288 )
289 }
290 "postgres" => {
291 format!(
292 "postgres://{}:{}@{}:{}/{}",
293 self.username.as_deref().unwrap_or("postgres"),
294 self.password.as_deref().unwrap_or(""),
295 self.host.as_deref().unwrap_or("localhost"),
296 self.port.unwrap_or(5432),
297 self.database
298 )
299 }
300 _ => panic!("不支持的数据库类型: {}", self.r#type),
301 }
302 }
303}