1pub mod app;
7pub mod config;
8pub mod errors;
9pub mod http;
10pub mod routing;
11pub mod traits;
12pub mod utils;
13
14pub mod container {
16 use std::collections::HashMap;
18 use std::any::Any;
19
20 pub struct Container {
21 services: HashMap<String, Box<dyn Any + Send + Sync>>,
22 }
23
24 impl Container {
25 pub fn new() -> Self {
26 Self {
27 services: HashMap::new(),
28 }
29 }
30 }
31
32 impl Default for Container {
33 fn default() -> Self {
34 Self::new()
35 }
36 }
37}
38
39pub mod middleware {
40 use std::future::Future;
42 use std::pin::Pin;
43
44 pub type MiddlewareResult = Pin<Box<dyn Future<Output = Result<axum::response::Response, axum::response::Response>> + Send>>;
45}
46
47pub use app::Application;
49pub use config::Config;
50pub use container::Container;
51pub use errors::{RustisanError, Result, ValidationErrors, ValidationErrorDetails};
52pub use http::{Request, Response};
53pub use routing::{Router, Route, RouteGroup, RouteHandler};
54
55pub use axum;
57pub use serde;
58pub use serde_json;
59pub use tokio;
60pub use uuid;
61pub use chrono;
62pub use async_trait::async_trait;
63
64pub const VERSION: &str = env!("CARGO_PKG_VERSION");
66
67pub trait RustisanApp {
69 fn configure(&mut self) -> Result<()>;
71
72 async fn run(&self) -> Result<()>;
74}
75
76#[macro_export]
78macro_rules! rustisan_app {
79 ($app_struct:ident) => {
80 impl $crate::RustisanApp for $app_struct {
81 fn configure(&mut self) -> $crate::Result<()> {
82 Ok(())
84 }
85
86 async fn run(&self) -> $crate::Result<()> {
87 Ok(())
89 }
90 }
91 };
92}
93
94pub fn init_logging() {
96 use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
97
98 tracing_subscriber::registry()
99 .with(fmt::layer())
100 .with(EnvFilter::from_default_env())
101 .init();
102}
103
104pub fn create_app() -> Application {
106 Application::new()
107}
108
109pub fn create_app_with_config(config: Config) -> Application {
111 Application::with_config(config)
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn test_version() {
120 assert!(!VERSION.is_empty());
121 }
122
123 #[test]
124 fn test_create_app() {
125 let app = create_app();
126 assert_eq!(app.config().app_name, "Rustisan Application");
127 }
128
129 #[tokio::test]
130 async fn test_create_app_with_config() {
131 let mut config = Config::default();
132 config.app_name = "Test App".to_string();
133
134 let app = create_app_with_config(config);
135 assert_eq!(app.config().app_name, "Test App");
136 }
137}