207 lines
5.3 KiB
Rust
207 lines
5.3 KiB
Rust
use serde::Deserialize;
|
|
use std::fmt::{Display, Formatter};
|
|
use std::net::IpAddr;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
#[non_exhaustive]
|
|
pub struct MagnetarNetworking {
|
|
pub host: String,
|
|
pub port: u16,
|
|
pub bind_addr: IpAddr,
|
|
pub protocol: MagnetarNetworkingProtocol,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum MagnetarNetworkingProtocol {
|
|
Http,
|
|
Https,
|
|
}
|
|
|
|
impl AsRef<str> for MagnetarNetworkingProtocol {
|
|
fn as_ref(&self) -> &str {
|
|
match *self {
|
|
MagnetarNetworkingProtocol::Http => "http",
|
|
MagnetarNetworkingProtocol::Https => "https",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for MagnetarNetworkingProtocol {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.as_ref())
|
|
}
|
|
}
|
|
|
|
fn env_host() -> String {
|
|
std::env::var("MAG_C_HOST")
|
|
.expect("MAG_C_HOST or \"networking.host\" in the default configuration must be set")
|
|
}
|
|
|
|
fn env_bind_addr() -> IpAddr {
|
|
std::env::var("MAG_C_BIND_ADDR")
|
|
.unwrap_or_else(|_| "::".to_owned())
|
|
.parse()
|
|
.map_err(|e| format!("Failed to parse \"MAG_C_BIND_ADDR\": {e}"))
|
|
.unwrap()
|
|
}
|
|
|
|
fn env_port() -> u16 {
|
|
std::env::var("MAG_C_PORT")
|
|
.unwrap_or_else(|_| "4939".to_owned())
|
|
.parse()
|
|
.expect("MAG_C_PORT must be a valid port number")
|
|
}
|
|
|
|
fn env_protocol() -> MagnetarNetworkingProtocol {
|
|
match std::env::var("MAG_C_PROTOCOL")
|
|
.unwrap_or_else(|_| "https".to_owned())
|
|
.to_lowercase()
|
|
.as_str()
|
|
{
|
|
"http" => MagnetarNetworkingProtocol::Http,
|
|
"https" => MagnetarNetworkingProtocol::Https,
|
|
_ => panic!("MAG_C_PROTOCOL must be a valid protocol"),
|
|
}
|
|
}
|
|
|
|
impl Default for MagnetarNetworking {
|
|
fn default() -> Self {
|
|
MagnetarNetworking {
|
|
host: env_host(),
|
|
bind_addr: env_bind_addr(),
|
|
port: env_port(),
|
|
protocol: env_protocol(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
#[non_exhaustive]
|
|
pub struct MagnetarCalckeyFrontendConfig {
|
|
pub bind_addr: IpAddr,
|
|
pub port: u16,
|
|
}
|
|
|
|
fn env_fe_bind_addr() -> IpAddr {
|
|
std::env::var("MAG_C_CK_FE_BIND_ADDR")
|
|
.unwrap_or_else(|_| "::".to_owned())
|
|
.parse()
|
|
.map_err(|e| format!("Failed to parse \"MAG_C_CK_FE_BIND_ADDR\": {e}"))
|
|
.unwrap()
|
|
}
|
|
|
|
fn env_fe_port() -> u16 {
|
|
std::env::var("MAG_C_CK_FE_PORT")
|
|
.unwrap_or_else(|_| "4938".to_owned())
|
|
.parse()
|
|
.expect("MAG_C_CK_FE_PORT must be a valid port number")
|
|
}
|
|
|
|
impl Default for MagnetarCalckeyFrontendConfig {
|
|
fn default() -> Self {
|
|
MagnetarCalckeyFrontendConfig {
|
|
bind_addr: env_fe_bind_addr(),
|
|
port: env_fe_port(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
#[non_exhaustive]
|
|
pub struct MagnetarBranding {
|
|
pub name: String,
|
|
pub version: String,
|
|
pub homepage: String,
|
|
pub repository: String,
|
|
}
|
|
|
|
fn env_brand_name() -> String {
|
|
std::env::var("MAG_C_BR_NAME").unwrap_or_else(|_| "magnetar".to_owned())
|
|
}
|
|
|
|
fn env_brand_version() -> String {
|
|
std::env::var("MAG_C_BR_VERSION").unwrap_or_else(|_| env!("CARGO_PKG_VERSION").to_owned())
|
|
}
|
|
|
|
fn env_brand_homepage() -> String {
|
|
std::env::var("MAG_C_BR_HOMEPAGE")
|
|
.unwrap_or_else(|_| "https://git.astolfo.cool/natty/magnetar".to_owned())
|
|
}
|
|
|
|
fn env_brand_repository() -> String {
|
|
std::env::var("MAG_C_BR_REPOSITORY")
|
|
.unwrap_or_else(|_| "https://git.astolfo.cool/natty/magnetar".to_owned())
|
|
}
|
|
|
|
impl Default for MagnetarBranding {
|
|
fn default() -> Self {
|
|
MagnetarBranding {
|
|
name: env_brand_name(),
|
|
version: env_brand_version(),
|
|
homepage: env_brand_homepage(),
|
|
repository: env_brand_repository(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
#[non_exhaustive]
|
|
pub struct MagnetarData {
|
|
pub database_url: String,
|
|
pub redis_url: String,
|
|
}
|
|
|
|
fn env_database_url() -> String {
|
|
std::env::var("MAG_C_DATABASE_URL")
|
|
.or_else(|_| std::env::var("DATABASE_URL"))
|
|
.expect("MAG_C_DATABASE_URL, DATABASE_URL or \"data.database_url\" in the default configuration must be set")
|
|
}
|
|
|
|
fn env_redis_url() -> String {
|
|
std::env::var("MAG_C_REDIS_URL")
|
|
.expect("MAG_C_REDIS_URL or \"data.redis_url\" in the default configuration must be set")
|
|
}
|
|
|
|
impl Default for MagnetarData {
|
|
fn default() -> Self {
|
|
MagnetarData {
|
|
database_url: env_database_url(),
|
|
redis_url: env_redis_url(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Debug, Default)]
|
|
#[non_exhaustive]
|
|
pub struct MagnetarConfig {
|
|
#[serde(default)]
|
|
pub networking: MagnetarNetworking,
|
|
#[serde(default)]
|
|
pub branding: MagnetarBranding,
|
|
#[serde(default)]
|
|
pub calckey_frontend: MagnetarCalckeyFrontendConfig,
|
|
#[serde(default)]
|
|
pub data: MagnetarData,
|
|
}
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum MagnetarConfigError {
|
|
#[error("Failed to load configuration: {0}")]
|
|
IoError(#[from] std::io::Error),
|
|
#[error("Failed to parse configuration: {0}")]
|
|
DeserializeError(#[from] toml::de::Error),
|
|
}
|
|
|
|
pub fn load_config() -> Result<MagnetarConfig, MagnetarConfigError> {
|
|
let path =
|
|
std::env::var("MAG_CONFIG_PATH").unwrap_or_else(|_| "config/default.toml".to_owned());
|
|
|
|
let str_cfg = std::fs::read_to_string(path)?;
|
|
|
|
let config = toml::from_str(&str_cfg)?;
|
|
|
|
Ok(config)
|
|
}
|