diff --git a/docs/content/web-frameworks.md b/docs/content/web-frameworks.md index 4b6db2a2..ee7abb2f 100644 --- a/docs/content/web-frameworks.md +++ b/docs/content/web-frameworks.md @@ -1,6 +1,6 @@ # Web framework integration -Maud includes support for these web frameworks: [Actix], [Rocket], [Rouille], [Tide], [Axum], [Poem], and [Salvo]. +Maud includes support for these web frameworks: [Actix], [Rocket], [Rouille], [Tide], [Axum], [Poem], [Salvo], and [Ntex]. [Actix]: https://actix.rs/ [Rocket]: https://rocket.rs/ @@ -11,6 +11,7 @@ Maud includes support for these web frameworks: [Actix], [Rocket], [Rouille], [T [Submillisecond]: https://github.com/lunatic-solutions/submillisecond [Poem]: https://github.com/poem-web/poem [Salvo]: https://salvo.rs +[Ntex]: https://ntex.rs/ # Actix @@ -304,3 +305,41 @@ async fn main() { Server::new(listener).serve(app).await; } ``` + +# Ntex + +ntex support is available with the "ntex" feature: + +```toml +# ... +[dependencies] +maud = { version = "*", features = ["ntex"] } +# ... +``` + +ntex request handlers can use a `Markup` that implements the `ntex::web::Responder` trait. + +```rust,no_run +use ntex::web::{get, App, HttpServer, Responder}; +use maud::{html, Markup}; +use std::io; + +#[get("/")] +async fn index() -> impl Responder { + html! { + html { + body { + h1 { "Hello World!" } + } + } + } +} + +#[ntex::main] +async fn main() -> io::Result<()> { + HttpServer::new(|| App::new().service(index)) + .bind(("127.0.0.1", 8080))? + .run() + .await +} +``` diff --git a/doctest/Cargo.toml b/doctest/Cargo.toml index 8dd7c47c..20f2fceb 100644 --- a/doctest/Cargo.toml +++ b/doctest/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] actix-web = { version = "4.0.0-rc.2", default-features = false, features = ["macros"] } ammonia = "3" -maud = { path = "../maud", features = ["actix-web", "rocket", "tide", "axum", "warp", "submillisecond", "poem", "salvo"] } +maud = { path = "../maud", features = ["actix-web", "rocket", "tide", "axum", "warp", "submillisecond", "poem", "salvo", "ntex"] } pulldown-cmark = "0.8" rocket = "0.5" rouille = "3" @@ -18,6 +18,7 @@ axum = "0.8" warp = "0.3.6" poem = "3" salvo = "0.78.0" +ntex = { version = "2" } [dependencies.async-std] version = "1.9.0" diff --git a/maud/Cargo.toml b/maud/Cargo.toml index 74eaa467..00809234 100644 --- a/maud/Cargo.toml +++ b/maud/Cargo.toml @@ -21,6 +21,7 @@ default = [] actix-web = ["actix-web-dep", "futures-util"] axum = ["axum-core", "http"] salvo = ["salvo_core", "http"] +ntex = ["dep:ntex"] [dependencies] maud_macros = { version = "0.27.0", path = "../maud_macros" } @@ -35,6 +36,7 @@ http = { version = "1", optional = true } warp = { version = "0.3.6", optional = true } poem = { version = "3", optional = true } salvo_core = { version = "0.78.0", optional = true } +ntex = { version = "2.0", optional = true, default-features = false } [dev-dependencies] trybuild = { version = "1.0.33", features = ["diff"] } diff --git a/maud/src/lib.rs b/maud/src/lib.rs index 67ce9c6f..3e28ff23 100644 --- a/maud/src/lib.rs +++ b/maud/src/lib.rs @@ -343,6 +343,58 @@ mod actix_support { } } +#[cfg(feature = "ntex")] +mod ntex_support { + use core::{ + error::Error, + task::{Context, Poll}, + }; + use ntex::{ + http::{ + body::{Body, BodySize, MessageBody}, + header, StatusCode, + }, + util::Bytes, + web::{ErrorRenderer, HttpRequest, HttpResponse, Responder}, + }; + + use crate::PreEscaped; + use alloc::{rc::Rc, string::String}; + + impl MessageBody for PreEscaped { + fn size(&self) -> BodySize { + self.0.size() + } + + fn poll_next_chunk( + &mut self, + cx: &mut Context<'_>, + ) -> Poll>>> { + self.0.poll_next_chunk(cx) + } + } + + impl From> for Body { + fn from(s: PreEscaped) -> Body { + s.0.into_bytes().into() + } + } + + impl<'a> From<&'a PreEscaped> for Body { + fn from(s: &'a PreEscaped) -> Body { + Body::Bytes(Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(&s.0))) + } + } + + impl Responder for PreEscaped { + async fn respond_to(self, _: &HttpRequest) -> HttpResponse { + HttpResponse::build(StatusCode::OK) + .header(header::CONTENT_TYPE, "text/html; charset=utf-8") + .body(self.0) + } + } +} + #[cfg(feature = "tide")] mod tide_support { use crate::PreEscaped;