diff --git a/Cargo.lock b/Cargo.lock index 0277ee7..4f472da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,6 +116,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -445,6 +494,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "cmake" version = "0.1.50" @@ -460,6 +549,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "cookie" version = "0.18.1" @@ -760,6 +855,7 @@ dependencies = [ "bytes", "cbc", "chrono", + "clap", "cookie", "hex", "html-escape", @@ -1072,6 +1168,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -1315,6 +1417,12 @@ dependencies = [ "serde", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -2342,6 +2450,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -2763,6 +2877,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.9.1" @@ -3193,7 +3313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc077306b38288262e5ba01d4b21532a6987416cdc0aedf04bb06c22a68fdc" dependencies = [ "anyhow", - "heck", + "heck 0.4.1", "indexmap", "wit-parser", ] @@ -3273,7 +3393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "557567f2793508760cd855f7659b7a0b9dc4dbc451f53f1415d6943a15311ade" dependencies = [ "anyhow", - "heck", + "heck 0.4.1", "proc-macro2", "quote", "shellexpand", diff --git a/Cargo.toml b/Cargo.toml index aee7622..4cc75a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ brotli = "6.0.0" bytes = "1.6.0" cbc = { version = "0.1.2", features = ["std"] } chrono = { version = "0.4.38", features = ["serde"] } +clap = { version = "4.5.18", features = ["derive", "env"] } cookie = "0.18.1" hex = "0.4.3" html-escape = "0.2.13" diff --git a/src/config/config.rs b/src/config/config.rs index 698c739..a57753e 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -201,11 +201,33 @@ fn default_max_compressed_body_size() -> usize { 3000000 } -fn read_config() -> Result { - let toml_exists = Path::new("edgee.toml").exists(); - let yaml_exists = Path::new("edgee.yaml").exists(); +fn read_config(path: Option<&Path>) -> Result { + let toml_path = Path::new("edgee.toml"); + let yaml_path = Path::new("edgee.yaml"); + + if let Some(path) = path { + let extension = path + .extension() + .and_then(|extension| extension.to_str()) + .expect("provided configuration file does not have a format extension or is invalid"); + + let config_data = + std::fs::read_to_string(path).expect("should read provided configuration file"); + + match extension { + "toml" => { + return toml::from_str(&config_data) + .map_err(|e| format!("should parse config file: {e}")) + } + "yml" | "yaml" => { + return serde_yml::from_str(&config_data) + .map_err(|e| format!("should parse config file: {e}")); + } + _ => return Err("provided configuration file has an unknown extension".to_string()), + } + } - match (toml_exists, yaml_exists) { + match (toml_path.exists(), yaml_path.exists()) { (true, true) => { Err("both edgee.toml and edgee.yaml exist but only one is expected.".into()) } @@ -213,24 +235,21 @@ fn read_config() -> Result { Err("no configuration file found, either edgee.toml or edgee.yaml is required.".into()) } (true, false) => { - let config_file = - std::fs::read_to_string("edgee.toml").expect("should read edgee.toml"); + let config_file = std::fs::read_to_string(toml_path).expect("should read edgee.toml"); toml::from_str(&config_file).map_err(|e| format!("should parse config file: {}", e)) } (false, true) => { - let config_file = - std::fs::read_to_string("edgee.yaml").expect("should read edgee.yaml"); + let config_file = std::fs::read_to_string(yaml_path).expect("should read edgee.yaml"); serde_yml::from_str(&config_file) .map_err(|e| format!("should parse config file: {}", e)) } } } -// TODO: Read config from CLI arguments // TODO: Add more configuration validations // TODO: Improve error messages for configuration errors -pub fn init() { - let config = read_config().expect("should read config file"); +pub fn init(path: Option<&Path>) { + let config = read_config(path).expect("should read config file"); config.validate().unwrap(); CONFIG.set(config).expect("Should initialize config"); diff --git a/src/main.rs b/src/main.rs index 3a33a1d..a003b12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +use std::path::PathBuf; + +use clap::Parser; use tracing::error; mod config; @@ -7,9 +10,18 @@ mod proxy; mod server; mod tools; +#[derive(Debug, Parser)] +#[command(about, author, version)] +struct Options { + #[arg(short = 'f', long = "config", env = "EDGEE_CONFIG_PATH")] + config_path: Option, +} + #[tokio::main] async fn main() { - config::config::init(); + let options = Options::parse(); + + config::config::init(options.config_path.as_deref()); logger::logger::init(); proxy::compute::data_collection::components::init();