2024-03-07 01:02:24 +05:00
|
|
|
use dotenvy::dotenv;
|
2024-04-11 18:29:27 +05:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::{env, fs};
|
2024-03-07 01:02:24 +05:00
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2024-03-07 01:02:24 +05:00
|
|
|
pub struct Config {
|
|
|
|
pub database: Database,
|
|
|
|
pub server: Server,
|
|
|
|
pub jwt: Jwt,
|
|
|
|
}
|
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2024-03-07 01:02:24 +05:00
|
|
|
pub struct Database {
|
|
|
|
pub host: String,
|
|
|
|
pub port: i32,
|
|
|
|
pub user: String,
|
|
|
|
pub password: String,
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2024-03-07 01:02:24 +05:00
|
|
|
pub struct Server {
|
|
|
|
pub address: String,
|
|
|
|
pub port: i32,
|
|
|
|
}
|
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2024-03-07 01:02:24 +05:00
|
|
|
pub struct Jwt {
|
|
|
|
pub secret: String,
|
|
|
|
pub expires_in: String,
|
2024-03-21 22:19:32 +05:00
|
|
|
pub maxage: i64,
|
2024-03-07 01:02:24 +05:00
|
|
|
}
|
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
fn evar(key: &str) -> Result<String, env::VarError> {
|
|
|
|
env::var(format!("ELNAFO_{}", key))
|
|
|
|
}
|
|
|
|
|
2024-03-07 01:02:24 +05:00
|
|
|
impl Config {
|
|
|
|
pub fn new() -> Self {
|
2024-04-11 18:29:27 +05:00
|
|
|
Config::default()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_env(&mut self) -> Result<&Self, ConfigError> {
|
2024-03-07 01:02:24 +05:00
|
|
|
dotenv().ok();
|
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
self.database.host = evar("DATABASE_HOST").unwrap_or(self.database.host.to_owned());
|
|
|
|
self.database.port = evar("DATABASE_PORT")
|
|
|
|
.unwrap_or(self.database.port.to_string())
|
|
|
|
.parse()?;
|
|
|
|
self.database.user = evar("DATABASE_USER").unwrap_or(self.database.user.to_owned());
|
|
|
|
self.database.password =
|
|
|
|
evar("DATABASE_PASSWORD").unwrap_or(self.database.password.to_owned());
|
|
|
|
self.database.name = evar("DATABASE_NAME").unwrap_or(self.database.name.to_owned());
|
|
|
|
|
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn open(path: &std::path::Path) -> Result<Config, ConfigError> {
|
|
|
|
fs::read_to_string(path)?.parse()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn data_dir() -> Result<std::path::PathBuf, ConfigError> {
|
|
|
|
let cwd = std::env::current_dir()?;
|
|
|
|
if cfg!(debug_assertions) {
|
|
|
|
Ok(cwd.join("temp"))
|
|
|
|
} else {
|
|
|
|
Ok(cwd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_string(&self) -> Result<String, ConfigError> {
|
|
|
|
Ok(toml::to_string(self)?)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write(&self, path: &std::path::Path) -> Result<(), ConfigError> {
|
|
|
|
Ok(fs::write(path, self.to_string()?)?)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn database_url(&self) -> String {
|
|
|
|
format!(
|
|
|
|
"postgres://{}:{}@{}:{}/{}",
|
|
|
|
self.database.user,
|
|
|
|
self.database.password,
|
|
|
|
self.database.host,
|
|
|
|
self.database.port,
|
|
|
|
self.database.name
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Config {
|
|
|
|
fn default() -> Self {
|
2024-03-07 01:02:24 +05:00
|
|
|
Config {
|
|
|
|
database: Database {
|
2024-04-11 18:29:27 +05:00
|
|
|
host: String::from("localhost"),
|
|
|
|
port: 5432,
|
|
|
|
user: String::from("elnafo"),
|
|
|
|
password: String::from("test"),
|
|
|
|
name: String::from("elnafo"),
|
2024-03-07 01:02:24 +05:00
|
|
|
},
|
|
|
|
server: Server {
|
2024-04-11 18:29:27 +05:00
|
|
|
address: String::from("127.0.0.1"),
|
|
|
|
port: 54600,
|
2024-03-07 01:02:24 +05:00
|
|
|
},
|
|
|
|
jwt: Jwt {
|
2024-04-11 18:29:27 +05:00
|
|
|
secret: String::from("change_this_secret"),
|
|
|
|
expires_in: String::from("60m"),
|
|
|
|
maxage: 3600,
|
2024-03-07 01:02:24 +05:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-11 18:29:27 +05:00
|
|
|
impl std::str::FromStr for Config {
|
|
|
|
type Err = ConfigError;
|
|
|
|
fn from_str(s: &str) -> Result<Self, ConfigError> {
|
|
|
|
toml::from_str(s).map_err(|_| ConfigError::Parse)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ConfigError {
|
|
|
|
Parse,
|
|
|
|
StringParse,
|
|
|
|
Serialize,
|
|
|
|
IO,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for ConfigError {}
|
|
|
|
|
|
|
|
impl std::fmt::Display for ConfigError {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
match self {
|
|
|
|
Self::Parse => write!(f, "Failed to parse Config from string"),
|
|
|
|
Self::StringParse => write!(f, "Failed to parse environment variable"),
|
|
|
|
Self::Serialize => write!(f, "Failed to serialize Config to TOML"),
|
|
|
|
Self::IO => write!(f, "Faild to write file"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<toml::ser::Error> for ConfigError {
|
|
|
|
fn from(_: toml::ser::Error) -> Self {
|
|
|
|
ConfigError::Serialize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<std::io::Error> for ConfigError {
|
|
|
|
fn from(_: std::io::Error) -> Self {
|
|
|
|
ConfigError::IO
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<std::num::ParseIntError> for ConfigError {
|
|
|
|
fn from(_: std::num::ParseIntError) -> Self {
|
|
|
|
ConfigError::StringParse
|
2024-03-07 01:02:24 +05:00
|
|
|
}
|
|
|
|
}
|