vertigo_cli/serve/
response_state.rs

1use actix_web::http::StatusCode;
2use std::collections::HashMap;
3
4use vertigo::AutoJsJson;
5
6fn content_type(content_type: &str) -> HashMap<String, String> {
7    let mut headers = HashMap::new();
8    headers.insert("content-type".into(), content_type.into());
9    headers
10}
11
12fn content_type_html() -> HashMap<String, String> {
13    content_type("text/html; charset=utf-8")
14}
15
16fn content_type_plain() -> HashMap<String, String> {
17    content_type("text/plain")
18}
19
20#[derive(AutoJsJson, Debug)]
21pub struct ResponseState {
22    pub status: u16,
23    pub headers: HashMap<String, String>,
24    pub body: Vec<u8>,
25}
26
27impl ResponseState {
28    pub const HTML: &'static str = "text/html; charset=utf-8";
29    pub const PLAIN: &'static str = "text/plain";
30
31    pub fn html(status: StatusCode, body: impl Into<String>) -> Self {
32        Self {
33            status: status.as_u16(),
34            headers: content_type_html(),
35            body: body.into().into_bytes(),
36        }
37    }
38
39    pub fn plain(status: StatusCode, body: impl Into<String>) -> Self {
40        Self {
41            status: status.as_u16(),
42            headers: content_type_plain(),
43            body: body.into().into_bytes(),
44        }
45    }
46
47    pub fn internal_error(body: impl Into<String>) -> Self {
48        Self {
49            status: StatusCode::INTERNAL_SERVER_ERROR.as_u16(),
50            headers: content_type_plain(),
51            body: body.into().into_bytes(),
52        }
53    }
54
55    pub fn add_watch_script(&mut self, port_watch: u16) {
56        let watch = include_str!("./watch.js");
57
58        let start = format!("start_watch('http://127.0.0.1:{port_watch}/events');");
59
60        let chunks = ["<script>", watch, &start, "</script>"];
61
62        let script = chunks.join("\n").into_bytes();
63        self.body.extend(script);
64    }
65}
66
67impl From<ResponseState> for actix_web::HttpResponse {
68    fn from(value: ResponseState) -> Self {
69        let status =
70            StatusCode::from_u16(value.status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
71        let mut builder = actix_web::HttpResponse::build(status);
72
73        for (name, value) in value.headers {
74            builder.insert_header((name, value));
75        }
76
77        builder.body(value.body)
78    }
79}