1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Use cargo rdme to generate the README.md file from this doc comment.
//! An opinionated batteries-included approach to a rust web framework.
//!
//! The idea is to take the best parts of the rust ecosystem and combine them into a framework that is easy to use and provides a good developer experience.
//!
//! # Installation
//!
//! Add the following to your `Cargo.toml` file.
//!
//! ```toml
//! [dependencies]
//! swim = "0.2"
//! ```
//!
//! # Features
//!
//! - Go blazingly fast with [hyper](https://github.com/hyperium/hyper) and [tokio](https://github.com/tokio-rs/tokio)
//! - Powerful routing with [routerify](https://github.com/routerify/routerify)
//! - CLI tooling with [cargo-swim](cargo-swim) (coming soon)
//! - Database support with [SeaORM](https://github.com/SeaQL/sea-orm) (planned)
//! - Templating with [Tera](https://github.com/Keats/tera) (planned)
//! - Dependency injection (planned)
//!
//! # Building a project
//!
//! You define a project by defining a struct that implements the `Project` trait. It is the highest-level abstraction in the framework. It is responsible for defining the settings, apps, and middleware for your project.
//!
//! ```ignore
//! use swim::prelude::*;
//!
//! struct MyProject;
//!
//! impl Project for MyProject {
//! fn settings(&self) -> Settings {
//! Settings::builder()
//! .extend_ron(relative!("settings.ron"))
//! .build()
//! .unwrap()
//! }
//!
//! fn apps(&self) -> Vec<Box<dyn App>> {
//! vec! [
//! MyApp.into()
//! ]
//! }
//!
//! fn middleware(&self) -> Vec<Box<dyn Middleware>> {
//! vec! [
//! MyMiddleware.into()
//! ]
//! }
//! }
//!
//! ```
//!
//! # Building apps
//!
//! You define an app by defining a struct that implements the `App` trait. It is responsible for defining the routes and views for your app.
//!
//! ```ignore
//! use swim::prelude::*;
//!
//! struct MyApp;
//!
//! impl App for MyApp {
//! fn mount(&self) -> &'static str {
//! "/"
//! }
//!
//! fn config(&self) -> AppConfig {
//! AppConfig::with_name("MyApp")
//! }
//!
//! fn models(&self) -> Vec<Box<dyn Model>> {
//! vec! []
//! }
//!
//! fn routes(&self) -> Vec<Route> {
//! vec! [
//! Route::new("/", IndexView),
//! Route::new("/hello", HelloView),
//! Route::new("/greeting/:name", GreetingView),
//! ]
//! }
//! }
//!
//! ```
//!
//! # Building views
//!
//! You define a view by defining a struct that implements the `View` trait. It is responsible for handling the request and returning a response. You can implement the specific HTTP methods you want to handle.
//!
//! ```ignore
//! #[derive(Debug)]
//! pub struct HelloView;
//!
//! #[async_trait::async_trait]
//! impl View for HelloView {
//! async fn get(&self, request: Request<Body>) -> Result<Response<Body>> {
//! Ok(Response::builder()
//! .status(StatusCode::OK)
//! .body(Body::from("Say hello to Swim! "))
//! .unwrap())
//! }
//!
//! async fn post(&self, request: Request<Body>) -> Result<Response<Body>> {
//! Ok(Response::builder()
//! .status(StatusCode::OK)
//! .body(Body::from("It's a post request! "))
//! .unwrap())
//! }
//! }
//!
//! ```
//!
//! # Defining middlewares
//!
//! You define a middleware by defining a struct that implements the `Middleware` trait. You may hook into the `pre` and `post` methods which are capable of modifying the upcoming request and leaving response respectively (or you could simply use these for monitoring traffic).
//!
//! ```ignore
//! ##[derive(Debug)]
//! pub struct Logger;
//!
//! #[async_trait::async_trait]
//! impl Middleware for Logger {
//! async fn pre(&self, request: Request<Body>) -> Result<Request<Body>> {
//! println! ("New request: {:?}", request.uri());
//!
//! Ok(request)
//! }
//!
//! async fn post(&self, response: Response<Body>) -> Result<Response<Body>> {
//! println! ("Response: {:?}", response.status());
//!
//! Ok(response)
//! }
//! }
//! ```
//!
//! # Running the project
//!
//! You may use the elegant swim macro to run your project.
//!
//! ```ignore
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! swim! (MyProject, host = "localhost", port = 8000);
//! }
//! ```
/// Prelude for the `swim` crate.
/// Crates that are used internally by the `swim` crate.
pub use async_trait;
pub use hyper;
pub use routerify;
// Re-exports
pub use ;
/// Various utilities that are helpful while building a Swim application.