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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
#[macro_use] extern crate mime; extern crate iron; extern crate serde; extern crate serde_json; use iron::prelude::*; use iron::{AfterMiddleware, typemap}; use iron::modifier::Modifier; use iron::headers::ContentType; use serde::ser::Serialize as ToJson; use serde_json::value::{self, Value as Json}; #[derive(Clone)] pub struct JsonResponse { value: Json, callback: Option<String>, } impl JsonResponse { pub fn new<T: ToJson>(value: T, callback: Option<String>) -> JsonResponse { JsonResponse { value: value::to_value(&value).unwrap_or(Json::Null), callback: callback, } } pub fn json<T: ToJson>(value: T) -> JsonResponse { JsonResponse::new(value, None) } pub fn jsonp<T: ToJson>(value: T, cb_name: String) -> JsonResponse { JsonResponse::new(value, Some(cb_name)) } } pub struct JsonResponseMiddleware; impl JsonResponseMiddleware { pub fn new() -> Self { JsonResponseMiddleware {} } } impl typemap::Key for JsonResponseMiddleware { type Value = JsonResponse; } impl Modifier<Response> for JsonResponse { fn modify(self, resp: &mut Response) { resp.extensions.insert::<JsonResponseMiddleware>(self); } } impl AfterMiddleware for JsonResponseMiddleware { fn after(&self, _: &mut Request, r: Response) -> IronResult<Response> { let mut resp = r; let header_body = resp.extensions .remove::<JsonResponseMiddleware>() .and_then(|j| { if let Ok(json_string) = serde_json::to_string(&j.value) { match j.callback { Some(ref cb) => { let mut jsonp = String::new(); jsonp.push_str(cb); jsonp.push('('); jsonp.push_str(&json_string); jsonp.push(')'); Some((ContentType(mime!(Text/Javascript; Charset=Utf8)), jsonp)) } None => Some((ContentType::json(), json_string)), } } else { None } }); if let Some((content_type, body)) = header_body { if !resp.headers.has::<ContentType>() { resp.headers.set(content_type); } resp.set_mut(body); } Ok(resp) } fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> { err.response = try!(self.after(req, err.response)); Err(err) } }