Skip to main content

moduvex_starter_web/
lib.rs

1//! # moduvex-starter-web
2//!
3//! Web application starter for Moduvex. One dependency, zero boilerplate.
4//!
5//! Bundles: runtime, HTTP server, module system, config, and observability
6//! with sensible defaults for web services.
7//!
8//! ```rust,ignore
9//! use moduvex_starter_web::prelude::*;
10//!
11//! #[moduvex::main]
12//! async fn main() {
13//!     Moduvex::new().run().await;
14//! }
15//! ```
16
17pub mod tracing_middleware;
18
19// ── Re-exports ──
20
21pub use moduvex_config;
22pub use moduvex_core;
23pub use moduvex_http;
24pub use moduvex_observe;
25pub use moduvex_runtime;
26pub use tracing_middleware::TracingMiddleware;
27
28// ── Default config ──
29
30/// Embedded default configuration for web applications.
31/// User's `app.toml` overrides these values.
32pub const WEB_DEFAULTS: &str = r#"
33[server]
34port = 8080
35host = "0.0.0.0"
36
37[observe.log]
38level = "info"
39format = "pretty"
40
41[observe.metrics]
42enabled = true
43"#;
44
45/// Create a [`ConfigLoader`] pre-loaded with web defaults.
46///
47/// Merge order: WEB_DEFAULTS → app.toml → app-{profile}.toml → env vars.
48pub fn load_config(
49    name: &str,
50    dir: &std::path::Path,
51) -> Result<moduvex_config::ConfigLoader, moduvex_config::ConfigError> {
52    moduvex_config::ConfigLoader::load_with_defaults(WEB_DEFAULTS, name, dir)
53}
54
55/// Create a [`ConfigLoader`] from defaults only (no file needed).
56pub fn default_config() -> Result<moduvex_config::ConfigLoader, moduvex_config::ConfigError> {
57    moduvex_config::ConfigLoader::from_defaults(WEB_DEFAULTS)
58}
59
60// ── Prelude ──
61
62pub mod prelude {
63    // Core framework
64    pub use moduvex_core::prelude::*;
65
66    // HTTP types + extractors
67    pub use moduvex_http::{
68        FromRequest, HttpServer, IntoHandler, Json, Middleware, Path, Query, Request, Response,
69        Router, State, StatusCode,
70    };
71
72    // Config
73    pub use moduvex_config::{ConfigLoader, Profile};
74
75    // Observability macros
76    pub use moduvex_observe::{debug, error, info, trace_event, warn};
77    pub use moduvex_observe::{Counter, Gauge, Histogram, Span};
78
79    // Tracing
80    pub use crate::TracingMiddleware;
81
82    // Starter helpers
83    pub use crate::{default_config, load_config, WEB_DEFAULTS};
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn default_config_loads_web_defaults() {
92        let loader = default_config().unwrap();
93        let raw = loader.raw();
94        let server = raw.get("server").unwrap().as_table().unwrap();
95        assert_eq!(server["port"].as_integer().unwrap(), 8080);
96        assert_eq!(server["host"].as_str().unwrap(), "0.0.0.0");
97    }
98
99    #[test]
100    fn web_defaults_parses_as_valid_toml() {
101        // Validates that from_defaults succeeds (proves valid TOML).
102        let loader = default_config().unwrap();
103        assert!(loader.raw().as_table().is_some());
104    }
105}