2018-11-24 16:44:53 +13:00
|
|
|
# Web framework integration
|
|
|
|
|
2021-01-22 19:31:51 +13:00
|
|
|
Maud includes support for these web frameworks:
|
2021-11-06 22:44:10 +11:00
|
|
|
[Actix], [Rocket], [Rouille], and [Tide].
|
2018-11-24 16:44:53 +13:00
|
|
|
|
|
|
|
[Actix]: https://actix.rs/
|
|
|
|
[Rocket]: https://rocket.rs/
|
|
|
|
[Rouille]: https://github.com/tomaka/rouille
|
2021-08-05 21:22:05 -07:00
|
|
|
[Tide]: https://docs.rs/tide/
|
2018-11-24 16:44:53 +13:00
|
|
|
|
|
|
|
# Actix
|
|
|
|
|
|
|
|
Actix support is available with the "actix-web" feature:
|
|
|
|
|
|
|
|
```toml
|
|
|
|
# ...
|
|
|
|
[dependencies]
|
|
|
|
maud = { version = "*", features = ["actix-web"] }
|
|
|
|
# ...
|
|
|
|
```
|
|
|
|
|
2021-01-22 19:31:51 +13:00
|
|
|
Actix request handlers can use a `Markup`
|
|
|
|
that implements the `actix_web::Responder` trait.
|
2018-11-24 16:44:53 +13:00
|
|
|
|
2021-01-15 17:40:46 +13:00
|
|
|
```rust,no_run
|
|
|
|
use actix_web::{get, App, HttpServer, Result as AwResult};
|
2018-11-24 16:44:53 +13:00
|
|
|
use maud::{html, Markup};
|
2021-01-15 17:40:46 +13:00
|
|
|
use std::io;
|
|
|
|
|
|
|
|
#[get("/")]
|
|
|
|
async fn index() -> AwResult<Markup> {
|
|
|
|
Ok(html! {
|
|
|
|
html {
|
|
|
|
body {
|
|
|
|
h1 { "Hello World!" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2018-11-24 16:44:53 +13:00
|
|
|
}
|
|
|
|
|
2021-01-15 17:40:46 +13:00
|
|
|
#[actix_web::main]
|
|
|
|
async fn main() -> io::Result<()> {
|
|
|
|
HttpServer::new(|| App::new().service(index))
|
|
|
|
.bind(("127.0.0.1", 8080))?
|
|
|
|
.run()
|
|
|
|
.await
|
2018-11-24 16:44:53 +13:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Rocket
|
|
|
|
|
2021-01-22 19:31:51 +13:00
|
|
|
Rocket works in a similar way,
|
|
|
|
except using the `rocket` feature:
|
2018-11-24 16:44:53 +13:00
|
|
|
|
|
|
|
```toml
|
|
|
|
# ...
|
|
|
|
[dependencies]
|
|
|
|
maud = { version = "*", features = ["rocket"] }
|
|
|
|
# ...
|
|
|
|
```
|
|
|
|
|
2021-01-22 19:31:51 +13:00
|
|
|
This adds a `Responder` implementation for the `Markup` type,
|
|
|
|
so you can return the result directly:
|
2018-11-24 16:44:53 +13:00
|
|
|
|
2021-01-15 17:40:46 +13:00
|
|
|
```rust,no_run
|
|
|
|
#![feature(decl_macro)]
|
|
|
|
|
2018-11-24 16:44:53 +13:00
|
|
|
use maud::{html, Markup};
|
2019-03-16 19:53:24 +13:00
|
|
|
use rocket::{get, routes};
|
2018-11-24 16:44:53 +13:00
|
|
|
use std::borrow::Cow;
|
|
|
|
|
|
|
|
#[get("/<name>")]
|
|
|
|
fn hello<'a>(name: Cow<'a, str>) -> Markup {
|
|
|
|
html! {
|
|
|
|
h1 { "Hello, " (name) "!" }
|
|
|
|
p { "Nice to meet you!" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
rocket::ignite().mount("/", routes![hello]).launch();
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Rouille
|
|
|
|
|
2021-01-22 19:31:51 +13:00
|
|
|
Unlike with the other frameworks,
|
|
|
|
Rouille doesn't need any extra features at all!
|
|
|
|
Calling `Response::html` on the rendered `Markup` will Just Work®.
|
2018-11-24 16:44:53 +13:00
|
|
|
|
2021-01-15 17:40:46 +13:00
|
|
|
```rust,no_run
|
2018-11-24 16:44:53 +13:00
|
|
|
use maud::html;
|
2019-03-16 19:53:24 +13:00
|
|
|
use rouille::{Response, router};
|
2018-11-24 16:44:53 +13:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
rouille::start_server("localhost:8000", move |request| {
|
|
|
|
router!(request,
|
|
|
|
(GET) (/{name: String}) => {
|
2021-01-15 17:40:46 +13:00
|
|
|
Response::html(html! {
|
2018-11-24 16:44:53 +13:00
|
|
|
h1 { "Hello, " (name) "!" }
|
|
|
|
p { "Nice to meet you!" }
|
2021-01-15 17:40:46 +13:00
|
|
|
})
|
2018-11-24 16:44:53 +13:00
|
|
|
},
|
|
|
|
_ => Response::empty_404()
|
|
|
|
)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
```
|
2021-08-05 21:22:05 -07:00
|
|
|
|
|
|
|
# Tide
|
|
|
|
|
|
|
|
Tide support is available with the "tide" feature:
|
|
|
|
|
|
|
|
```toml
|
|
|
|
# ...
|
|
|
|
[dependencies]
|
|
|
|
maud = { version = "*", features = ["tide"] }
|
|
|
|
# ...
|
|
|
|
```
|
|
|
|
|
2021-11-29 22:06:56 +11:00
|
|
|
This adds an implementation of `From<PreEscaped<String>>`
|
|
|
|
for the `Response` struct.
|
|
|
|
Once provided,
|
|
|
|
callers may return results of `html!` directly as responses:
|
2021-08-05 21:22:05 -07:00
|
|
|
|
|
|
|
```rust,no_run
|
|
|
|
use maud::html;
|
|
|
|
use tide::Request;
|
|
|
|
use tide::prelude::*;
|
|
|
|
|
|
|
|
#[async_std::main]
|
|
|
|
async fn main() -> tide::Result<()> {
|
|
|
|
let mut app = tide::new();
|
|
|
|
app.at("/hello/:name").get(|req: Request<()>| async move {
|
|
|
|
let name: String = req.param("name")?.parse()?;
|
|
|
|
Ok(html! {
|
|
|
|
h1 { "Hello, " (name) "!" }
|
|
|
|
p { "Nice to meet you!" }
|
|
|
|
})
|
|
|
|
});
|
|
|
|
app.listen("127.0.0.1:8080").await?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
```
|
2021-08-17 09:25:07 +00:00
|
|
|
|
|
|
|
# Axum
|
|
|
|
|
|
|
|
Axum support is available with the "axum" feature:
|
|
|
|
|
|
|
|
```toml
|
|
|
|
# ...
|
|
|
|
[dependencies]
|
|
|
|
maud = { version = "*", features = ["axum"] }
|
|
|
|
# ...
|
|
|
|
```
|
|
|
|
|
|
|
|
This adds an implementation of `IntoResponse` for `Markup`/`PreEscaped<String>`.
|
|
|
|
This then allows you to use it directly as a response!
|
|
|
|
|
|
|
|
```rust,no_run
|
|
|
|
use maud::{html, Markup};
|
2021-12-08 09:12:00 +01:00
|
|
|
use axum::{Router, routing::get};
|
2021-08-17 09:25:07 +00:00
|
|
|
|
|
|
|
async fn hello_world() -> Markup {
|
2021-10-16 05:14:27 +02:00
|
|
|
html! {
|
|
|
|
h1 { "Hello, World!" }
|
2021-08-17 09:25:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
|
|
|
// build our application with a single route
|
2021-10-16 05:14:27 +02:00
|
|
|
let app = Router::new().route("/", get(hello_world));
|
2021-08-17 09:25:07 +00:00
|
|
|
|
|
|
|
// run it with hyper on localhost:3000
|
|
|
|
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
|
|
|
.serve(app.into_make_service())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
}
|
2021-10-16 05:14:27 +02:00
|
|
|
```
|