1pub mod app;
4pub mod error;
5pub mod http;
6pub mod log;
7pub mod macros;
8pub mod middleware;
9pub mod model;
10pub mod project;
11pub mod route;
12pub mod settings;
13pub mod sugar;
14pub mod view;
15
16use std::{
17 net::{Ipv4Addr, SocketAddr},
18 str::FromStr,
19 sync::Arc,
20};
21
22use routerify::{Router, RouterService};
23
24pub use crate::{
26 app::{App, AppConfig},
27 error::Error,
28 http::{Body, Request, Response, StatusCode},
29 middleware::{Logger, Middleware},
30 model::Model,
31 project::Project,
32 route::Route,
33 settings::{CoreSettings, DatabaseSettings, Settings},
34 view::View,
35};
36
37pub use async_trait;
39pub use hyper;
40pub use routerify;
41
42pub type Result<T> = std::result::Result<T, Error>;
46
47#[derive(Debug)]
51pub struct Swim {
52 project: Box<dyn Project>,
53 host: String,
54 port: u16,
55}
56
57impl Swim {
58 pub fn with(project: Box<dyn Project>) -> Self {
60 Self {
61 project,
62 host: "127.0.0.1".to_string(),
63 port: 8000,
64 }
65 }
66
67 pub fn host(mut self, host: &str) -> Self {
71 self.host = host.to_string();
72 self
73 }
74
75 pub fn port(mut self, port: u16) -> Self {
79 self.port = port;
80 self
81 }
82
83 pub async fn swim(self) -> Result<()> {
87 let ip_address = match self.host {
89 host if host == "localhost" => Ipv4Addr::LOCALHOST,
90 host => Ipv4Addr::from_str(&host)?,
91 };
92 let address = SocketAddr::from((ip_address, self.port));
93
94 let _settings = self.project.settings();
95 let apps = self.project.apps();
96
97 let mut middlewares: Vec<Box<dyn Middleware>> = vec![Box::new(Logger)];
100
101 middlewares.extend(self.project.middlewares());
103
104 project_details!(&self.project, &address);
106 for app in apps.iter() {
107 app_details!(app);
108 }
109 if !middlewares.is_empty() {
110 middleware_listing!(middlewares);
111 }
112
113 let get_router = || {
115 let mut builder = Router::<Body, Error>::builder();
116
117 for app in apps.iter() {
118 let mut scoped_router_builder = Router::builder();
119
120 for route in app.routes() {
121 let view_get = route.view.clone();
122 let view_post = route.view.clone();
123 let view_put = route.view.clone();
124 let view_patch = route.view.clone();
125 let view_delete = route.view.clone();
126
127 scoped_router_builder = scoped_router_builder.get(&route.path, move |req| {
129 let view = view_get.clone();
130 async move { view.get(req).await }
131 });
132
133 scoped_router_builder = scoped_router_builder.post(&route.path, move |req| {
135 let view = view_post.clone();
136 async move { view.post(req).await }
137 });
138
139 scoped_router_builder = scoped_router_builder.put(&route.path, move |req| {
141 let view = view_put.clone();
142 async move { view.put(req).await }
143 });
144
145 scoped_router_builder = scoped_router_builder.patch(&route.path, move |req| {
147 let view = view_patch.clone();
148 async move { view.patch(req).await }
149 });
150
151 scoped_router_builder = scoped_router_builder.delete(&route.path, move |req| {
153 let view = view_delete.clone();
154 async move { view.delete(req).await }
155 });
156 }
157
158 builder = builder.scope(app.mount(), scoped_router_builder.build().unwrap());
159 }
160
161 for middleware in middlewares.into_iter() {
163 let middleware = Arc::new(middleware);
164
165 let middleware_pre = middleware.clone();
167 builder = builder.middleware(routerify::Middleware::pre(move |req| {
168 let middleware_cloned = middleware_pre.clone();
169
170 async move { middleware_cloned.pre(req).await }
171 }));
172
173 let middleware_post = middleware.clone();
175 builder = builder.middleware(routerify::Middleware::post(move |res| {
176 let middleware_cloned = middleware_post.clone();
177
178 async move { middleware_cloned.post(res).await }
179 }));
180 }
181
182 builder.build().unwrap()
183 };
184
185 launch_info!(address);
187
188 let service = RouterService::new(get_router()).unwrap();
190
191 hyper::server::Server::try_bind(&address)?
193 .serve(service)
194 .await?;
195
196 Ok(())
197 }
198}