actix_web/types/
html.rs

1//! Semantic HTML responder. See [`Html`].
2
3use crate::{
4    http::{
5        header::{self, ContentType, TryIntoHeaderValue},
6        StatusCode,
7    },
8    HttpRequest, HttpResponse, Responder,
9};
10
11/// Semantic HTML responder.
12///
13/// When used as a responder, creates a 200 OK response, sets the correct HTML content type, and
14/// uses the string passed to [`Html::new()`] as the body.
15///
16/// ```
17/// # use actix_web::web::Html;
18/// Html::new("<p>Hello, World!</p>")
19/// # ;
20/// ```
21#[derive(Debug, Clone, PartialEq, Hash)]
22pub struct Html(String);
23
24impl Html {
25    /// Constructs a new `Html` responder.
26    pub fn new(html: impl Into<String>) -> Self {
27        Self(html.into())
28    }
29}
30
31impl Responder for Html {
32    type Body = String;
33
34    fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
35        let mut res = HttpResponse::with_body(StatusCode::OK, self.0);
36        res.headers_mut().insert(
37            header::CONTENT_TYPE,
38            ContentType::html().try_into_value().unwrap(),
39        );
40        res
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use crate::test::TestRequest;
48
49    #[test]
50    fn responder() {
51        let req = TestRequest::default().to_http_request();
52
53        let res = Html::new("<p>Hello, World!</p>");
54        let res = res.respond_to(&req);
55
56        assert!(res.status().is_success());
57        assert!(res
58            .headers()
59            .get(header::CONTENT_TYPE)
60            .unwrap()
61            .to_str()
62            .unwrap()
63            .starts_with("text/html"));
64        assert!(res.body().starts_with("<p>"));
65    }
66}