use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct CoolConfig {
pub init_db: bool,
pub init_menu: bool,
pub init_judge: String,
pub eps: bool,
pub tenant: Option<TenantConfig>,
pub i18n: Option<I18nConfig>,
pub crud: CrudConfig,
pub file: Option<FileConfig>,
pub redis: Option<RedisConfig>,
pub jwt: JwtConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct TenantConfig {
pub enable: bool,
#[serde(default)]
pub urls: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct I18nConfig {
pub enable: bool,
#[serde(default)]
pub languages: Vec<String>,
pub service_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrudConfig {
#[serde(default = "default_soft_delete")]
pub soft_delete: bool,
#[serde(default = "default_page_size")]
pub page_size: u64,
#[serde(default = "default_upsert")]
pub upsert: String,
}
impl Default for CrudConfig {
fn default() -> Self {
Self {
soft_delete: true,
page_size: 20,
upsert: "normal".to_string(),
}
}
}
fn default_soft_delete() -> bool {
true
}
fn default_page_size() -> u64 {
20
}
fn default_upsert() -> String {
"normal".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileConfig {
pub mode: String,
pub domain: Option<String>,
pub oss: Option<OssConfig>,
pub cos: Option<CosConfig>,
pub qiniu: Option<QiniuConfig>,
pub aws: Option<AwsConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OssConfig {
pub access_key_id: String,
pub access_key_secret: String,
pub bucket: String,
pub endpoint: String,
pub timeout: Option<String>,
pub exp_after: Option<u64>,
pub max_size: Option<u64>,
pub host: Option<String>,
pub public_domain: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CosConfig {
pub access_key_id: String,
pub access_key_secret: String,
pub bucket: String,
pub region: String,
pub public_domain: String,
pub duration_seconds: Option<u64>,
pub allow_prefix: Option<String>,
pub allow_actions: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QiniuConfig {
pub access_key_id: String,
pub access_key_secret: String,
pub bucket: String,
pub region: String,
pub public_domain: String,
pub upload_url: Option<String>,
pub file_key: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AwsConfig {
pub access_key_id: String,
pub secret_access_key: String,
pub bucket: String,
pub region: String,
pub fields: Option<HashMap<String, String>>,
pub conditions: Option<Vec<serde_json::Value>>,
pub expires: Option<u64>,
pub public_domain: Option<String>,
pub force_path_style: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RedisConfig {
pub host: String,
pub port: u16,
pub password: Option<String>,
pub db: u8,
}
impl RedisConfig {
pub fn url(&self) -> String {
match &self.password {
Some(pwd) if !pwd.is_empty() => {
format!("redis://:{}@{}:{}/{}", pwd, self.host, self.port, self.db)
}
_ => format!("redis://{}:{}/{}", self.host, self.port, self.db),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JwtConfig {
#[serde(default = "default_jwt_secret")]
pub secret: String,
#[serde(default = "default_jwt_expire")]
pub expire: u64,
#[serde(default = "default_jwt_refresh_expire")]
pub refresh_expire: u64,
}
impl Default for JwtConfig {
fn default() -> Self {
Self {
secret: "cool-admin-rust".to_string(),
expire: 7200,
refresh_expire: 604800,
}
}
}
fn default_jwt_secret() -> String {
"cool-admin-rust".to_string()
}
fn default_jwt_expire() -> u64 {
7200
}
fn default_jwt_refresh_expire() -> u64 {
604800
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ModuleConfig {
pub name: String,
pub description: String,
#[serde(default)]
pub order: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseConfig {
pub r#type: String,
pub host: Option<String>,
pub port: Option<u16>,
pub username: Option<String>,
pub password: Option<String>,
pub database: String,
#[serde(default = "default_max_connections")]
pub max_connections: u32,
#[serde(default = "default_min_connections")]
pub min_connections: u32,
#[serde(default = "default_connect_timeout")]
pub connect_timeout: u64,
#[serde(default)]
pub logging: bool,
#[serde(default)]
pub synchronize: bool,
}
fn default_max_connections() -> u32 {
100
}
fn default_min_connections() -> u32 {
5
}
fn default_connect_timeout() -> u64 {
10
}
impl DatabaseConfig {
pub fn url(&self) -> String {
match self.r#type.as_str() {
"sqlite" => format!("sqlite://{}?mode=rwc", self.database),
"mysql" => {
format!(
"mysql://{}:{}@{}:{}/{}",
self.username.as_deref().unwrap_or("root"),
self.password.as_deref().unwrap_or(""),
self.host.as_deref().unwrap_or("localhost"),
self.port.unwrap_or(3306),
self.database
)
}
"postgres" => {
format!(
"postgres://{}:{}@{}:{}/{}",
self.username.as_deref().unwrap_or("postgres"),
self.password.as_deref().unwrap_or(""),
self.host.as_deref().unwrap_or("localhost"),
self.port.unwrap_or(5432),
self.database
)
}
_ => panic!("不支持的数据库类型: {}", self.r#type),
}
}
}