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",
|
"clap",
|
||||||
"color-print",
|
"color-print",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
|
@ -10,6 +10,7 @@ clap = { version = "4.5", features = ["derive"] }
|
||||||
color-print = "0.3"
|
color-print = "0.3"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }
|
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }
|
||||||
tokio = { version = "1.38", features = ["full"] }
|
tokio = { version = "1.38", features = ["full"] }
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
|
|
|
@ -1,56 +1,2 @@
|
||||||
// This module is only for the schema definition. Always use `Option<T>` for
|
mod client;
|
||||||
// optional values, and do not implement `Default`s or use `#[serde(default)]`s.
|
mod server;
|
||||||
// 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>,
|
|
||||||
}
|
|
||||||
|
|
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