1#[macro_use]
13extern crate rocket;
14
15mod cache;
16mod config;
17mod http_headers;
18#[cfg(test)]
19mod tests;
20mod tile_request;
21
22use cache::Cache;
23use cache::CachedFile;
24use config::Config;
25use figment::Figment;
26use rocket::Build;
27use rocket::Request;
28use rocket::Rocket;
29use rocket::State;
30use rocket_etag_if_none_match::EtagIfNoneMatch;
31use std::env;
32use tile_request::WmtsRequest;
33use tile_request::XyzRequest;
34
35#[catch(404)]
37fn general_not_found(req: &Request) -> String {
38 format!("Sorry, '{}' is not a valid path.", req.uri())
39}
40
41#[get("/wmts/<alias>?<request..>")]
43pub async fn wmts_tile(
44 app_cache: &State<Cache>,
45 etag_if_none_match: EtagIfNoneMatch<'_>,
46 alias: &str,
47 request: WmtsRequest,
48) -> Option<CachedFile> {
49 let req = request.with_alias(alias);
50 app_cache
51 .get_or_download_wmts(etag_if_none_match, req)
52 .await
53 .ok()
54}
55
56#[catch(404)]
58fn wmts_tile_not_found(req: &Request) -> String {
59 format!("Sorry, the WMTS tile for '{}' was not found.", req.uri())
60}
61
62#[get("/xyz/<alias>/<a>/<x>/<y>/<z>")]
64pub async fn xyz_tile<'a>(
65 app_cache: &State<Cache>,
66 etag_if_none_match: EtagIfNoneMatch<'_>,
67 alias: &str,
68 a: &str,
69 x: &str,
70 y: &str,
71 z: &str,
72) -> Option<CachedFile> {
73 let request = XyzRequest::new(alias, a, x, y, z);
74 app_cache
75 .get_or_download_xyz(etag_if_none_match, request)
76 .await
77 .ok()
78}
79
80#[catch(404)]
82fn xyz_tile_not_found(req: &Request) -> String {
83 format!("Sorry, the XYZ tile for '{}' was not found.", req.uri())
84}
85
86#[get("/")]
88fn index() -> &'static str {
89 "Hello, there is nothing here! Read the fully described manual ;)"
90}
91
92#[launch]
94fn rocket() -> _ {
95 match run(env::args().collect()) {
96 Ok(r) => r,
97 Err(e) => panic!("Error while launching: {}", e),
98 }
99}
100
101fn run(args: Vec<String>) -> Result<Rocket<Build>, String> {
103 if let Some(filepath) = args.get(1) {
104 let app_config: Config = Config::from_file(filepath);
105 let cache: Cache = Cache::new(app_config.clone());
106 dbg!(app_config.clone());
107 let new_figment = Figment::new()
108 .join(("ident", false)) .join(("port", app_config.port));
110 let figment = rocket::Config::figment().merge(new_figment);
111
112 Ok(rocket::custom(figment)
113 .attach(http_headers::CacheControl)
114 .attach(http_headers::Cors)
115 .manage(cache)
116 .mount("/", routes![index, wmts_tile, xyz_tile])
117 .register("/", catchers![general_not_found])
118 .register("/wmts", catchers![wmts_tile_not_found])
119 .register("/xyz", catchers![xyz_tile_not_found]))
120 } else {
121 Err("No configuration!".to_string())
122 }
123}