From ec03c5320815c6c61acf077916a7079c0522c24f Mon Sep 17 00:00:00 2001 From: naskya Date: Thu, 20 Jun 2024 04:46:10 +0900 Subject: [PATCH] add client config --- Cargo.lock | 1 + Cargo.toml | 1 + src/command/config/schema.rs | 58 +--------------------- src/command/config/schema/client.rs | 75 +++++++++++++++++++++++++++++ src/command/config/schema/server.rs | 58 ++++++++++++++++++++++ 5 files changed, 137 insertions(+), 56 deletions(-) create mode 100644 src/command/config/schema/client.rs create mode 100644 src/command/config/schema/server.rs diff --git a/Cargo.lock b/Cargo.lock index 79e3896..aa02784 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -425,6 +425,7 @@ dependencies = [ "clap", "color-print", "serde", + "serde_json", "sqlx", "thiserror", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 70b82c9..f0f79fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/command/config/schema.rs b/src/command/config/schema.rs index eaaf780..ea1769a 100644 --- a/src/command/config/schema.rs +++ b/src/command/config/schema.rs @@ -1,56 +1,2 @@ -// This module is only for the schema definition. Always use `Option` 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, -} - -#[derive(Deserialize, Serialize, Validate, Debug)] -pub(super) struct Network { - protocol: Option, - 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, - password: Option, - index: Option, - prefix: Option, -} - -#[derive(Deserialize, Serialize, Validate, Debug)] -pub(super) struct Id { - #[validate(range(min = 16, max = 24))] - length: Option, - fingerprint: Option, -} +mod client; +mod server; diff --git a/src/command/config/schema/client.rs b/src/command/config/schema/client.rs new file mode 100644 index 0000000..856bb5f --- /dev/null +++ b/src/command/config/schema/client.rs @@ -0,0 +1,75 @@ +//! Structure of the client config (`config/client.toml`) + +// This module is only for the schema definition. Always use `Option` 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, + /// Server-wide default light theme + dark_theme: Option, + #[validate(url)] + icon: Option, + #[validate(url)] + banner_image: Option, + #[validate(url)] + background_image: Option, + #[validate(custom(function = "is_color_code"))] + theme_color: Option, +} + +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(); + } +} diff --git a/src/command/config/schema/server.rs b/src/command/config/schema/server.rs new file mode 100644 index 0000000..a7c1244 --- /dev/null +++ b/src/command/config/schema/server.rs @@ -0,0 +1,58 @@ +//! Structure of the server config (`config/server.toml`) + +// This module is only for the schema definition. Always use `Option` 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, +} + +#[derive(Deserialize, Serialize, Validate, Debug)] +pub(super) struct Network { + protocol: Option, + 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, + password: Option, + index: Option, + prefix: Option, +} + +#[derive(Deserialize, Serialize, Validate, Debug)] +pub(super) struct Id { + #[validate(range(min = 16, max = 24))] + length: Option, + fingerprint: Option, +}