aboutsummaryrefslogtreecommitdiff
path: root/src/viewer/mod.rs
blob: a411c298f0b16770b3faa48c8f8c056c95b9e995 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use std::{convert::Infallible, net::SocketAddr, sync::Arc};

use warp::{hyper::StatusCode, Filter, Rejection, Reply};

use crate::{dimension::Dimension, render::Renderer, tiling::Tiler};

pub fn serve_http(dimension: Dimension, bind: SocketAddr) {
    tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap()
        .block_on(async move {
            let renderer = Renderer::new(dimension);
            let tiler = Arc::new(Tiler::new(renderer));
            let tiler: _ = warp::any().map(move || tiler.clone());

            let tiles = warp::path!("tiles" / isize / isize / isize)
                .and(tiler.clone())
                .and_then(|z, x, y, tiler: Arc<Tiler>| async move {
                    Ok::<_, Infallible>(warp::reply::with_header(
                        tiler.get_tile(z, x, y),
                        "content-type",
                        "image/png",
                    ))
                });

            let viewer_html: _ = warp::path!().and(warp::fs::file("./src/viewer/viewer.html"));
            let viewer_js: _ =
                warp::path!("viewer.js").and(warp::fs::file("./src/viewer/viewer.js"));

            let router: _ = tiles
                .or(viewer_html)
                .or(viewer_js)
                .recover(handle_rejection);

            warp::serve(router).run(bind).await;
        })
}

async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible> {
    let code;
    let message;
    if err.is_not_found() {
        code = StatusCode::NOT_FOUND;
        message = "Not found";
    } else if let Some(_) = err.find::<warp::reject::MethodNotAllowed>() {
        code = StatusCode::METHOD_NOT_ALLOWED;
        message = "Method not allowed";
    } else {
        eprintln!("unhandled rejection: {:?}", err);
        code = StatusCode::INTERNAL_SERVER_ERROR;
        message = "Unhandled rejection :(";
    }
    Ok(warp::reply::with_status(message, code))
}