diff --git a/Cargo.lock b/Cargo.lock index b43baeb..3806a5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.2" @@ -178,6 +189,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.5" @@ -242,6 +259,25 @@ dependencies = [ "inout", ] +[[package]] +name = "config" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" +dependencies = [ + "async-trait", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + [[package]] name = "cookie" version = "0.16.2" @@ -260,7 +296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" dependencies = [ "aes-gcm", - "base64", + "base64 0.21.5", "percent-encoding", "rand", "subtle", @@ -349,6 +385,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -537,6 +579,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -549,7 +600,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ - "base64", + "base64 0.21.5", "bytes", "headers-core", "http 1.0.0", @@ -755,7 +806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", ] [[package]] @@ -788,6 +839,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -800,6 +862,12 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -855,6 +923,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -893,6 +967,16 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -978,6 +1062,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown 0.12.3", +] + [[package]] name = "overload" version = "0.1.1" @@ -1007,12 +1101,63 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "pin-project" version = "1.1.3" @@ -1198,7 +1343,7 @@ version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64", + "base64 0.21.5", "bytes", "cookie 0.16.2", "cookie_store", @@ -1232,6 +1377,27 @@ dependencies = [ "winreg", ] +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64 0.13.1", + "bitflags 1.3.2", + "serde", +] + +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1365,6 +1531,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -1625,6 +1802,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "tower" version = "0.4.13" @@ -1727,6 +1913,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "unicode-bidi" version = "0.3.14" @@ -2042,6 +2234,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "zero-to-axum" version = "0.1.0-dev" @@ -2049,6 +2250,7 @@ dependencies = [ "anyhow", "axum", "axum-extra", + "config", "futures-util", "hyper 1.1.0", "pin-project", diff --git a/Cargo.toml b/Cargo.toml index 317ef91..a7eb80e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ license = "MIT OR Apache-2.0" anyhow = { version = "1.0.71", features = ["backtrace"] } axum = {version = "0.7", features = ["tokio", "http1", "http2"] } axum-extra = { version = "0.9.0", features = ["cookie-private", "typed-header"] } +config = { version = "0.13.4", features = ["toml"] } futures-util = "0.3" hyper = "1.1" pin-project = "1.1.0" diff --git a/conf/default.toml b/conf/default.toml new file mode 100644 index 0000000..75d0533 --- /dev/null +++ b/conf/default.toml @@ -0,0 +1,6 @@ +debug = true + +listen = "[::]:3742" + +[database] +url = "sqlite://./zero-to-axum.db" diff --git a/src/conf.rs b/src/conf.rs new file mode 100644 index 0000000..5ea95b3 --- /dev/null +++ b/src/conf.rs @@ -0,0 +1,31 @@ +use anyhow::Result; +use config::{Config, Environment, File}; +use serde::Deserialize; +use std::{env, net::SocketAddr}; + +#[derive(Debug, Deserialize)] +pub struct Database { + pub url: String, +} + +#[derive(Debug, Deserialize)] +#[allow(unused)] +pub struct Conf { + pub debug: bool, + pub database: Database, + pub listen: SocketAddr, +} + +impl Conf { + pub fn read() -> Result { + let mode = env::var("MODE").unwrap_or_else(|_| "dev".into()); + + let s = Config::builder() + .add_source(File::with_name("conf/default")) + .add_source(File::with_name(&format!("conf/{}", mode)).required(false)) + .add_source(Environment::with_prefix("z2a")) + .build()?; + + Ok(s.try_deserialize()?) + } +} diff --git a/src/lib.rs b/src/lib.rs index a2a89b7..0a8c5f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +pub mod conf; mod server; +pub use conf::Conf; pub use server::ZeroToAxum; diff --git a/src/main.rs b/src/main.rs index 939fd11..a38cbfd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use anyhow::{Context, Result}; -use zero_to_axum::ZeroToAxum; +use zero_to_axum::{Conf, ZeroToAxum}; fn init_tracing() { use tracing_subscriber::{filter::LevelFilter, fmt, EnvFilter}; @@ -15,8 +15,8 @@ fn init_tracing() { async fn main() -> Result<()> { init_tracing(); - let addr = "[::]:3742".parse().unwrap(); - let server = ZeroToAxum::serve(addr).await; + let conf = Conf::read()?; + let server = ZeroToAxum::serve(conf).await; server.await.context("run server") } diff --git a/src/server/mod.rs b/src/server/mod.rs index 252cbd0..d85a17f 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -10,6 +10,8 @@ use std::pin::pin; use std::pin::Pin; use tracing::info; +use crate::Conf; + #[pin_project] pub struct ZeroToAxum { #[pin] @@ -33,7 +35,7 @@ impl ZeroToAxum { self.bound_addr } - pub async fn serve(addr: SocketAddr) -> ZeroToAxum { + pub async fn serve(conf: Conf) -> ZeroToAxum { let state = AppState { // TODO: pull from config key: Key::generate(), @@ -41,11 +43,11 @@ impl ZeroToAxum { let app = routes::build().with_state(state); - let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); + let listener = tokio::net::TcpListener::bind(&conf.listen).await.unwrap(); let bound_addr = listener.local_addr().unwrap(); let server = axum::serve(listener, app); - info!("server started, listening on {addr:?}"); + info!("server started, listening on {bound_addr:?}"); ZeroToAxum { server: Box::pin(server.into_future()), diff --git a/tests/basic.rs b/tests/basic.rs index d9898cc..b334c02 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -13,3 +13,14 @@ async fn health_check() -> Result<()> { server.shutdown().await } + +#[traced(tokio::test)] +async fn config_reads_defaults() { + let conf = zero_to_axum::Conf::read().unwrap(); + + assert_eq!( + conf.listen, + "[::]:3742".parse().unwrap(), + "parse server listen addr" + ); +} diff --git a/tests/fixture/mod.rs b/tests/fixture/mod.rs index d74fdf8..fff3829 100644 --- a/tests/fixture/mod.rs +++ b/tests/fixture/mod.rs @@ -3,7 +3,7 @@ use futures_util::FutureExt; use std::net::SocketAddr; use tokio::task::JoinHandle; use tracing::info; -use zero_to_axum::ZeroToAxum; +use zero_to_axum::{Conf, ZeroToAxum}; pub struct TestServer { server_task_handle: JoinHandle<()>, @@ -13,7 +13,14 @@ pub struct TestServer { impl TestServer { pub async fn spawn() -> TestServer { info!("start server"); - let server = ZeroToAxum::serve("[::]:0".parse().unwrap()).await; + let server = ZeroToAxum::serve(Conf { + listen: "[::]:0".parse().unwrap(), + database: zero_to_axum::conf::Database { + url: "memory:".into(), + }, + debug: true, + }) + .await; let addr = server.local_addr(); let server_task_handle = tokio::spawn(server.map(|res| res.unwrap())); info!("server spawned");