swim/
lib.rs

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