add client config
This commit is contained in:
parent
2660ff9a70
commit
ec03c53208
5 changed files with 137 additions and 56 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -425,6 +425,7 @@ dependencies = [
|
|||
"clap",
|
||||
"color-print",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
|
|
|
@ -10,6 +10,7 @@ clap = { version = "4.5", features = ["derive"] }
|
|||
color-print = "0.3"
|
||||
thiserror = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }
|
||||
tokio = { version = "1.38", features = ["full"] }
|
||||
toml = "0.8"
|
||||
|
|
|
@ -1,56 +1,2 @@
|
|||
// This module is only for the schema definition. Always use `Option<T>` for
|
||||
// optional values, and do not implement `Default`s or use `#[serde(default)]`s.
|
||||
// Optional values are handled in the main Firefish program, and this tool
|
||||
// does not take care of it.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
type Port = u16;
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Config {
|
||||
network: Network,
|
||||
database: Database,
|
||||
cache_server: CacheServer,
|
||||
id: Option<Id>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Network {
|
||||
protocol: Option<HttpProtocol>,
|
||||
host: String,
|
||||
port: Port,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub(super) enum HttpProtocol {
|
||||
Https,
|
||||
Http,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Database {
|
||||
host: String,
|
||||
port: Port,
|
||||
user: String,
|
||||
password: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct CacheServer {
|
||||
host: String,
|
||||
port: Port,
|
||||
user: Option<String>,
|
||||
password: Option<String>,
|
||||
index: Option<String>,
|
||||
prefix: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Id {
|
||||
#[validate(range(min = 16, max = 24))]
|
||||
length: Option<u8>,
|
||||
fingerprint: Option<String>,
|
||||
}
|
||||
mod client;
|
||||
mod server;
|
||||
|
|
75
src/command/config/schema/client.rs
Normal file
75
src/command/config/schema/client.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
//! Structure of the client config (`config/client.toml`)
|
||||
|
||||
// This module is only for the schema definition. Always use `Option<T>` for
|
||||
// optional values, and do not implement `Default`s or use `#[serde(default)]`s.
|
||||
// Optional values are handled in the main Firefish program, and this tool
|
||||
// does not take care of it.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::{Validate, ValidationError};
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Config {
|
||||
appearance: Appearance,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Appearance {
|
||||
/// Server-wide default light theme
|
||||
light_theme: Option<String>,
|
||||
/// Server-wide default light theme
|
||||
dark_theme: Option<String>,
|
||||
#[validate(url)]
|
||||
icon: Option<String>,
|
||||
#[validate(url)]
|
||||
banner_image: Option<String>,
|
||||
#[validate(url)]
|
||||
background_image: Option<String>,
|
||||
#[validate(custom(function = "is_color_code"))]
|
||||
theme_color: Option<String>,
|
||||
}
|
||||
|
||||
fn is_color_code(color_code: &str) -> Result<(), ValidationError> {
|
||||
let length = color_code.len();
|
||||
|
||||
if length == 0 || !color_code.starts_with('#') {
|
||||
return Err(ValidationError::new(
|
||||
"color code must starts with a number sign",
|
||||
));
|
||||
}
|
||||
if length != (1 + 3) && length != (1 + 6) {
|
||||
return Err(ValidationError::new("color code must be 3 or 6 digits"));
|
||||
}
|
||||
if !color_code[1..]
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_digit() || ('a'..='f').contains(&c) || ('A'..='F').contains(&c))
|
||||
{
|
||||
return Err(ValidationError::new(
|
||||
"color code must be a hexadecimal number",
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit_test {
|
||||
#[test]
|
||||
fn is_color_code() {
|
||||
super::is_color_code("#fff").unwrap();
|
||||
super::is_color_code("#FFF").unwrap();
|
||||
super::is_color_code("#000").unwrap();
|
||||
super::is_color_code("#a32").unwrap();
|
||||
super::is_color_code("#101010").unwrap();
|
||||
super::is_color_code("#1ad010").unwrap();
|
||||
super::is_color_code("#f9d43c").unwrap();
|
||||
|
||||
super::is_color_code("#g9d43c").unwrap_err();
|
||||
super::is_color_code("#1234").unwrap_err();
|
||||
super::is_color_code("#1").unwrap_err();
|
||||
super::is_color_code("#a").unwrap_err();
|
||||
super::is_color_code("101010").unwrap_err();
|
||||
super::is_color_code("fff").unwrap_err();
|
||||
super::is_color_code("##fff").unwrap_err();
|
||||
super::is_color_code("なつ").unwrap_err();
|
||||
}
|
||||
}
|
58
src/command/config/schema/server.rs
Normal file
58
src/command/config/schema/server.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
//! Structure of the server config (`config/server.toml`)
|
||||
|
||||
// This module is only for the schema definition. Always use `Option<T>` for
|
||||
// optional values, and do not implement `Default`s or use `#[serde(default)]`s.
|
||||
// Optional values are handled in the main Firefish program, and this tool
|
||||
// does not take care of it.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
type Port = u16;
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Config {
|
||||
network: Network,
|
||||
database: Database,
|
||||
cache_server: CacheServer,
|
||||
id: Option<Id>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Network {
|
||||
protocol: Option<HttpProtocol>,
|
||||
host: String,
|
||||
port: Port,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub(super) enum HttpProtocol {
|
||||
Https,
|
||||
Http,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Database {
|
||||
host: String,
|
||||
port: Port,
|
||||
user: String,
|
||||
password: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct CacheServer {
|
||||
host: String,
|
||||
port: Port,
|
||||
user: Option<String>,
|
||||
password: Option<String>,
|
||||
index: Option<String>,
|
||||
prefix: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Validate, Debug)]
|
||||
pub(super) struct Id {
|
||||
#[validate(range(min = 16, max = 24))]
|
||||
length: Option<u8>,
|
||||
fingerprint: Option<String>,
|
||||
}
|
Loading…
Reference in a new issue