/
main.rs
76 lines (69 loc) · 2.51 KB
/
main.rs
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! An example web service using ructe with the nickel framework.
extern crate nickel;
extern crate time;
use nickel::hyper::header::{ContentType, Expires, HttpDate};
use nickel::hyper::server::Streaming;
use nickel::status::StatusCode;
use nickel::{Halt, HttpRouter, MiddlewareResult, Nickel, Request, Response};
use std::io::{self, Write};
use time::{now, Duration};
/// The main routine creates a Nickel server, adds a route for static
/// files and one for the front page of the server, and then runs the
/// server.
fn main() {
let mut server = Nickel::new();
server.get("/static/:name.:ext", static_file);
server.get("/", page);
server.listen("127.0.0.1:6767").expect("listen");
}
/// A handler for static files.
/// The request should have the parameters `name` and `ext` from the route.
/// If those match an existing file, serve it, with its correct
/// content type and a far expires header.
/// Otherwise return a 404 result.
fn static_file<'mw>(
req: &mut Request,
mut res: Response<'mw>,
) -> MiddlewareResult<'mw> {
if let (Some(name), Some(ext)) = (req.param("name"), req.param("ext")) {
use templates::statics::StaticFile;
if let Some(s) = StaticFile::get(&format!("{}.{}", name, ext)) {
res.set(ContentType(s.mime()));
res.set(Expires(HttpDate(now() + Duration::days(300))));
return res.send(s.content);
}
}
res.error(StatusCode::NotFound, "Not found")
}
/// A handler for the front page of the server.
/// Simple render a template with some arguments.
fn page<'mw>(
_req: &mut Request,
res: Response<'mw>,
) -> MiddlewareResult<'mw> {
use templates::page;
render(res, |o| page(o, &[("silly", 4), ("long", 7), ("final", 3)]))
}
fn render<F>(res: Response, do_render: F) -> MiddlewareResult
where
F: FnOnce(&mut Response<(), Streaming>) -> io::Result<()>,
{
let mut stream = res.start()?;
match do_render(&mut stream) {
Ok(()) => Ok(Halt(stream)),
Err(e) => stream.bail(format!("Problem rendering template: {:?}", e)),
}
}
/// This method can be used as a "template tag", that is a method that
/// can be called directly from a template.
fn footer(out: &mut impl Write) -> io::Result<()> {
templates::footer(
out,
&[
("ructe", "https://crates.io/crates/ructe"),
("nickel", "https://crates.io/crates/nickel"),
],
)
}
// And finally, include the generated code for templates and static files.
include!(concat!(env!("OUT_DIR"), "/templates.rs"));