diff --git a/.gitignore b/.gitignore index ea8c4bf..db38427 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +config.toml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 12d25fb..ea53ca6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -513,6 +513,12 @@ dependencies = [ "bytes", ] +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" + [[package]] name = "cc" version = "1.0.90" @@ -1101,9 +1107,12 @@ dependencies = [ "actix-web-lab", "anyhow", "askama", + "camino", "clap", "log", + "serde", "simplelog", + "toml", ] [[package]] @@ -1299,6 +1308,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1507,6 +1525,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.40" @@ -1773,6 +1825,15 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 20e408b..872e259 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,10 @@ actix-web = "4.5.1" actix-web-lab = "0.20.2" anyhow = "1.0.81" askama = "0.12.1" +camino = "1.1.6" clap = { version = "4.5.3", features = ["derive"] } log = "0.4.21" +serde = { version = "1.0.197", features = ["derive"] } simplelog = { version = "0.12.2", features = ["paris"] } +toml = "0.8.12" # time = { version = "0.3.34", features = ["macros"] } diff --git a/config.default.toml b/config.default.toml new file mode 100644 index 0000000..e80281f --- /dev/null +++ b/config.default.toml @@ -0,0 +1,5 @@ +debug=true + +[webserver] +host="0.0.0.0" +port=8080 \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 5484955..ab057dc 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -5,14 +5,17 @@ use clap::Parser; #[command(version, about, long_about = None)] pub struct CliArgs { /// Port to bind to - #[arg(short, long, default_value_t=8080)] - pub port: u16, + #[arg(short, long)] + pub port: Option, /// Host ip to bind to, usually not required to change - #[arg(long, default_value="0.0.0.0")] - pub host: String, + #[arg(long)] + pub host: Option, /// Extra debugging output #[arg(long, short)] - pub debug: bool + pub debug: bool, + + #[arg(long, short, default_value="./config.toml")] + pub config: camino::Utf8PathBuf, } \ No newline at end of file diff --git a/src/config/definition.rs b/src/config/definition.rs new file mode 100644 index 0000000..3e0e5ca --- /dev/null +++ b/src/config/definition.rs @@ -0,0 +1,13 @@ +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +pub struct Config { + pub debug: bool, + pub webserver: ConfigWebserver +} + +#[derive(Debug, Deserialize)] +pub struct ConfigWebserver { + pub host: String, + pub port: u16, +} \ No newline at end of file diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..7607853 --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,54 @@ +use std::borrow::{Borrow, BorrowMut}; + +use crate::cli::CliArgs; + +pub mod definition; + +const DEFAULT_CONFIG: &'static str = include_str!("../../config.default.toml"); + +pub struct ConfigManager { + inner: definition::Config, +} + +impl ConfigManager { + pub fn parse_and_join(cli: &CliArgs) -> anyhow::Result { + let data = if !cli.config.exists() { + log::warn!("Config doesnt exist, making it."); + std::fs::write(&cli.config, DEFAULT_CONFIG)?; + DEFAULT_CONFIG.to_string() + } else { + std::fs::read_to_string(&cli.config)? + }; + + let mut inner = toml::from_str::(&data)?; + + if let Some(host) = &cli.host { + inner.webserver.host = host.clone(); + } + + if let Some(port) = cli.port { + inner.webserver.port = port; + } + + if cli.debug { + inner.debug = true; + } + + + Ok(Self { + inner + }) + } + + pub fn get_ref(&self) -> &definition::Config { + self.inner.borrow() + } + + #[allow(dead_code)] + pub fn get_mut(&mut self) -> &mut definition::Config { + self.inner.borrow_mut() + } +} + + + diff --git a/src/main.rs b/src/main.rs index 1fe181e..bc0138c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,14 +3,23 @@ use clap::Parser; mod public; mod logger; mod cli; +mod config; #[actix_web::main] async fn main() -> std::io::Result<()> { let cli = cli::CliArgs::parse(); logger::init_logger(&cli); + let config = match config::ConfigManager::parse_and_join(&cli) { + Ok(r) => r, + Err(e) => { + log::error!("Failed to parse configs: {e}"); + return Ok(()); + } + }; - if let Err(e) = public::start_actix(&cli).await { + + if let Err(e) = public::start_actix(config.get_ref()).await { log::error!("Actix had an error: {e}"); } Ok(()) diff --git a/src/public/mod.rs b/src/public/mod.rs index 45f37d7..bf9455a 100644 --- a/src/public/mod.rs +++ b/src/public/mod.rs @@ -5,10 +5,10 @@ mod templates; use actix_web::{web, App, HttpServer}; use actix_files as actix_fs; -use crate::cli::CliArgs; +use crate::config::definition::Config; -pub(crate) async fn start_actix(cli: &CliArgs) -> anyhow::Result<()> { - let bindip = format!("{}:{}", cli.host, cli.port); +pub(crate) async fn start_actix(config: &Config) -> anyhow::Result<()> { + let bindip = format!("{}:{}", config.webserver.host, config.webserver.port); log::info!("Serving an http server at http://{bindip}"); HttpServer::new(|| {