aboutsummaryrefslogtreecommitdiffstats
path: root/src/config
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2026-02-03 13:45:46 +0200
committerrtkay123 <dev@kanjala.com>2026-02-03 13:45:46 +0200
commiteb2e86997d47249aa31b703598de13ab2eb96caa (patch)
tree9a591adee7d027b305d07a04987b5559b99f4d37 /src/config
parent0ea3cb1d4743b922fbc6e07037096e75caffba8f (diff)
downloadsellershut-master.tar.bz2
sellershut-master.zip
feat: add cacheHEADmaster
Diffstat (limited to 'src/config')
-rw-r--r--src/config/cache.rs57
-rw-r--r--src/config/cli/cache/mod.rs46
-rw-r--r--src/config/cli/mod.rs (renamed from src/config/cli.rs)50
-rw-r--r--src/config/cli/oauth/mod.rs36
-rw-r--r--src/config/mod.rs35
5 files changed, 182 insertions, 42 deletions
diff --git a/src/config/cache.rs b/src/config/cache.rs
new file mode 100644
index 0000000..96f3a9b
--- /dev/null
+++ b/src/config/cache.rs
@@ -0,0 +1,57 @@
+use serde::Deserialize;
+use url::Url;
+
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub struct CacheConfig {
+ #[serde(rename = "dsn")]
+ pub redis_dsn: Url,
+ #[serde(default)]
+ pub pooled: bool,
+ #[serde(rename = "type")]
+ pub kind: RedisVariant,
+ #[serde(default = "default_max_conns")]
+ #[serde(rename = "max-connections")]
+ pub max_connections: u16,
+}
+
+#[derive(Debug, Deserialize, Clone, Default)]
+#[serde(rename_all = "kebab-case")]
+pub enum RedisVariant {
+ Clustered,
+ #[default]
+ NonClustered,
+ Sentinel(SentinelConfig),
+}
+
+#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
+pub struct SentinelConfig {
+ #[serde(rename = "sentinel_service_name")]
+ pub service_name: String,
+ #[serde(default)]
+ pub redis_tls_mode_secure: bool,
+ pub redis_db: Option<i64>,
+ pub redis_username: Option<String>,
+ pub redis_password: Option<String>,
+ #[serde(default)]
+ pub redis_use_resp3: bool,
+}
+
+fn default_max_conns() -> u16 {
+ 100
+}
+
+fn default_cache() -> Url {
+ Url::parse("redis://localhost:6379").expect("valid default DATABASE url")
+}
+
+impl Default for CacheConfig {
+ fn default() -> Self {
+ Self {
+ redis_dsn: default_cache(),
+ pooled: Default::default(),
+ kind: Default::default(),
+ max_connections: default_max_conns(),
+ }
+ }
+}
diff --git a/src/config/cli/cache/mod.rs b/src/config/cli/cache/mod.rs
new file mode 100644
index 0000000..04b36bc
--- /dev/null
+++ b/src/config/cli/cache/mod.rs
@@ -0,0 +1,46 @@
+use clap::{Parser, ValueEnum};
+use serde::Deserialize;
+use url::Url;
+
+#[derive(Debug, Clone, Parser, Deserialize, Default)]
+pub struct Cache {
+ /// Cache connection string
+ #[arg(long, env = "CACHE_URL", default_value = "redis://localhost:6379")]
+ pub cache_url: Option<Url>,
+ #[arg(long, env = "CACHE_POOL_ENABLED", default_value = "true")]
+ pub cache_pooled: Option<bool>,
+ #[serde(rename = "type")]
+ #[arg(long, env = "CACHE_TYPE", default_value = "non-clustered")]
+ pub cache_type: Option<RedisVariant>,
+ #[serde(default = "default_max_conns")]
+ #[serde(rename = "max-connections")]
+ #[arg(long, env = "CACHE_MAX_CONNECTIONS", default_value = "100")]
+ pub cache_max_conn: Option<u16>,
+ #[command(flatten)]
+ pub sentinel_config: SentinelConfig,
+}
+
+#[derive(Debug, Deserialize, Clone, ValueEnum)]
+#[serde(rename_all = "kebab-case")]
+pub enum RedisVariant {
+ Clustered,
+ NonClustered,
+ Sentinel,
+}
+
+fn default_max_conns() -> Option<u16> {
+ Some(100)
+}
+
+#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Parser, Default)]
+pub struct SentinelConfig {
+ #[serde(rename = "sentinel_service_name")]
+ #[arg(long, env = "CACHE_SENTINEL_NAME", default_value = "true")]
+ pub service_name: Option<String>,
+ #[serde(default)]
+ #[arg(long, env = "CACHE_TLS_MODE_SECURE")]
+ pub cache_tls_mode_secure: bool,
+ #[serde(default)]
+ #[arg(long, env = "CACHE_USE_RESP3")]
+ pub cache_use_resp3: bool,
+}
diff --git a/src/config/cli.rs b/src/config/cli/mod.rs
index be1b913..81eb2fe 100644
--- a/src/config/cli.rs
+++ b/src/config/cli/mod.rs
@@ -1,9 +1,11 @@
+pub mod cache;
+
+#[cfg(feature = "oauth")]
+pub mod oauth;
+
use std::path::PathBuf;
use clap::Parser;
-#[cfg(feature = "oauth-discord")]
-use secrecy::SecretString;
-use serde::Deserialize;
use url::Url;
use crate::config::{logging::LogLevel, port::port_in_range};
@@ -31,14 +33,17 @@ pub struct Cli {
#[arg(short, long, env = "TIMEOUT_SECONDS", default_value = "10")]
pub timeout_duration: Option<u64>,
- /// Users database connection string
+ /// Database connection string
#[arg(
long,
- env = "USERS_DATABASE_URL",
+ env = "DATABASE_URL",
default_value = "postgres://postgres:password@localhost:5432/sellershut"
)]
pub db: Option<Url>,
+ #[command(flatten)]
+ pub cache: Option<cache::Cache>,
+
/// Server's system name
#[arg(short, long, default_value = "sellershut", env = "SYSTEM_NAME")]
pub system_name: Option<String>,
@@ -50,37 +55,7 @@ pub struct Cli {
/// Oauth optionas
#[command(flatten)]
#[cfg(feature = "oauth")]
- pub oauth: OAuth,
-}
-
-#[derive(Debug, Clone, Parser, Deserialize)]
-pub struct OAuth {
- #[cfg(feature = "oauth-discord")]
- #[command(flatten)]
- discord: DiscordOauth,
- #[arg(long, env = "OAUTH_REDIRECT_URL")]
- oauth_redirect_url: Option<Url>,
-}
-
-#[cfg(feature = "oauth-discord")]
-#[derive(Debug, Clone, Parser, Deserialize, Default)]
-pub struct DiscordOauth {
- #[arg(long, env = "OAUTH_DISCORD_CLIENT_ID")]
- discord_client_id: Option<String>,
- #[arg(long, env = "OAUTH_DISCORD_CLIENT_SECRET")]
- discord_client_secret: Option<SecretString>,
- #[arg(
- long,
- env = "OAUTH_DISCORD_TOKEN_URL",
- default_value = "https://discord.com/api/oauth2/token"
- )]
- discord_token_url: Option<Url>,
- #[arg(
- long,
- env = "OAUTH_DISCORD_AUTH_URL",
- default_value = "https://discord.com/api/oauth2/authorize?response_type=code"
- )]
- discord_auth_url: Option<Url>,
+ pub oauth: oauth::OAuth,
}
#[cfg(test)]
@@ -95,7 +70,8 @@ impl Default for Cli {
domain: Default::default(),
system_name: Default::default(),
environment: Default::default(),
- oauth: None,
+ oauth: Default::default(),
+ cache: Default::default(),
db: url,
}
}
diff --git a/src/config/cli/oauth/mod.rs b/src/config/cli/oauth/mod.rs
new file mode 100644
index 0000000..4bf1c34
--- /dev/null
+++ b/src/config/cli/oauth/mod.rs
@@ -0,0 +1,36 @@
+use clap::Parser;
+#[cfg(feature = "oauth-discord")]
+use secrecy::SecretString;
+use serde::Deserialize;
+#[cfg(feature = "oauth")]
+use url::Url;
+
+#[derive(Debug, Clone, Parser, Deserialize, Default)]
+pub struct OAuth {
+ #[cfg(feature = "oauth-discord")]
+ #[command(flatten)]
+ discord: DiscordOauth,
+ #[arg(long, env = "OAUTH_REDIRECT_URL")]
+ oauth_redirect_url: Option<Url>,
+}
+
+#[cfg(feature = "oauth-discord")]
+#[derive(Debug, Clone, Parser, Deserialize, Default)]
+pub struct DiscordOauth {
+ #[arg(long, env = "OAUTH_DISCORD_CLIENT_ID")]
+ discord_client_id: Option<String>,
+ #[arg(long, env = "OAUTH_DISCORD_CLIENT_SECRET")]
+ discord_client_secret: Option<SecretString>,
+ #[arg(
+ long,
+ env = "OAUTH_DISCORD_TOKEN_URL",
+ default_value = "https://discord.com/api/oauth2/token"
+ )]
+ discord_token_url: Option<Url>,
+ #[arg(
+ long,
+ env = "OAUTH_DISCORD_AUTH_URL",
+ default_value = "https://discord.com/api/oauth2/authorize?response_type=code"
+ )]
+ discord_auth_url: Option<Url>,
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 7495b22..e64ae5c 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -1,13 +1,15 @@
+pub mod cache;
mod cli;
mod logging;
mod port;
pub use cli::Cli;
-#[cfg(feature = "oauth")]
-use secrecy::SecretString;
use serde::Deserialize;
use url::Url;
-use crate::config::logging::LogLevel;
+use crate::config::{
+ cache::{CacheConfig, RedisVariant},
+ logging::LogLevel,
+};
#[derive(Default, Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
@@ -23,6 +25,8 @@ pub struct Config {
#[serde(default)]
pub database: DatabaseOptions,
#[serde(default)]
+ pub cache: CacheConfig,
+ #[serde(default)]
pub server: Api,
#[serde(default)]
#[cfg(feature = "oauth")]
@@ -65,7 +69,7 @@ pub struct OAuth {
#[serde(rename_all = "kebab-case")]
pub struct DiscordOauth {
pub client_id: String,
- pub client_secret: SecretString,
+ pub client_secret: secrecy::SecretString,
#[serde(default = "discord_token_url")]
pub token_url: Url,
#[serde(default = "discord_auth_url")]
@@ -94,7 +98,7 @@ impl Default for OAuth {
#[cfg(feature = "oauth-discord")]
discord: DiscordOauth {
client_id: String::default(),
- client_secret: SecretString::default(),
+ client_secret: secrecy::SecretString::default(),
token_url: discord_token_url(),
auth_url: discord_auth_url(),
},
@@ -175,6 +179,7 @@ impl Config {
pub fn merge_with_cli(&mut self, cli: &Cli) {
let server = &mut self.server;
let dsn = &mut self.database;
+ let cache = &mut self.cache;
if let Some(port) = cli.port {
server.port = port;
@@ -195,6 +200,26 @@ impl Config {
if let Some(db_url) = &cli.db {
dsn.url = db_url.clone();
}
+
+ if let Some(c) = cli.cache.as_ref().and_then(|v| v.cache_url.clone()) {
+ cache.redis_dsn = c;
+ }
+
+ if let Some(c) = cli.cache.as_ref().and_then(|v| v.cache_pooled) {
+ cache.pooled = c;
+ }
+
+ if let Some(c) = cli.cache.as_ref().and_then(|v| v.cache_max_conn) {
+ cache.max_connections = c;
+ }
+
+ if let Some(c) = cli.cache.as_ref().and_then(|v| v.cache_type.clone()) {
+ cache.kind = match c {
+ cli::cache::RedisVariant::Clustered => RedisVariant::Clustered,
+ cli::cache::RedisVariant::NonClustered => RedisVariant::NonClustered,
+ cli::cache::RedisVariant::Sentinel => cache.kind.clone(),
+ };
+ }
}
}