#[macro_use] extern crate nickel;
extern crate rustc_serialize;
extern crate regex;
use std::collections::BTreeMap;
use std::io::Write;
use nickel::status::StatusCode::{self, NotFound, BadRequest};
use nickel::{
Nickel, NickelError, Continue, Halt, Request, Response, MiddlewareResult,
QueryString, JsonBody, StaticFilesHandler, HttpRouter, Action, MediaType
};
use regex::Regex;
use rustc_serialize::json::{Json, ToJson};
#[derive(RustcDecodable, RustcEncodable)]
struct Person {
firstname: String,
lastname: String,
}
impl ToJson for Person {
fn to_json(&self) -> Json {
let mut map = BTreeMap::new();
map.insert("first_name".to_string(), self.firstname.to_json());
map.insert("last_name".to_string(), self.lastname.to_json());
Json::Object(map)
}
}
fn logger<'mw>(req: &mut Request, res: Response<'mw>) -> MiddlewareResult<'mw> {
println!("logging request from logger fn: {:?}", req.origin.uri);
Ok(Continue(res))
}
fn main() {
let mut server = Nickel::new();
server.utilize(middleware! { |request|
println!("logging request from middleware! macro: {:?}", request.origin.uri);
});
server.utilize(logger);
let mut router = Nickel::router();
router.get("/user/:userid", middleware! { |request|
format!("This is user: {}", request.param("userid").unwrap())
});
router.get("/bar", middleware!("This is the /bar handler"));
router.get("/content-type", middleware! { |_, mut response|
response.set(MediaType::Json);
"{'foo':'bar'}"
});
let hello_regex = Regex::new("/hello/(?P<name>[a-zA-Z]+)").unwrap();
router.get(hello_regex, middleware! { |request|
format!("Hello {}", request.param("name").unwrap())
});
router.get("/some/*/route", middleware! {
"This matches /some/crazy/route but not /some/super/crazy/route"
});
router.get("/a/**/route", middleware! {
"This matches /a/crazy/route and also /a/super/crazy/route"
});
router.post("/a/post/request", middleware! { |request, response|
let person = request.json_as::<Person>().unwrap();
format!("Hello {} {}", person.firstname, person.lastname)
});
router.get("/api/person/1", middleware! {
let person = Person {
firstname: "Pea".to_string(),
lastname: "Nut".to_string()
};
person.to_json()
});
router.get("/query", middleware! { |request|
if let Some(vals) = request.query().all("foo") {
format!("Your foo values in the query string are: {:?}", vals)
} else {
format!("You didn't provide any foo values!")
}
});
router.get("/strict", middleware! { |request|
if request.query().get("state") != Some("valid") {
(BadRequest, "Error Parsing JSON")
} else {
(StatusCode::Ok, "Congratulations on conforming!")
}
});
server.utilize(router);
server.utilize(StaticFilesHandler::new("examples/assets/"));
fn custom_404<'a>(err: &mut NickelError, _req: &mut Request) -> Action {
if let Some(ref mut res) = err.stream {
if res.status() == NotFound {
let _ = res.write_all(b"<h1>Call the police!</h1>");
return Halt(())
}
}
Continue(())
}
let custom_handler: fn(&mut NickelError, &mut Request) -> Action = custom_404;
server.handle_error(custom_handler);
server.listen("127.0.0.1:6767");
}