Repository: actix/actix-web
File: src/json.rs (Rust)

Code before:
        self
    }

    /// Add allowed content type
    pub fn content_type(&mut self, content_type: ContentTypeFilter) -> &mut Self {
        self.content_types.push(content_type);
        self
    }
}

impl<S> Default for JsonConfig<S> {
    fn default() -> Self {
        let mut content_types = Vec::new();
        content_types.push(ContentTypeFilter::new(None, Some(mime::JSON), None));
        content_types.push(ContentTypeFilter::new(None, None, Some(mime::JSON)));
        JsonConfig {
            limit: 262_144,
            ehandler: Rc::new(|e, _| e.into()),
            content_types,
        }
    }
}

/// Filter type for allowed `Content-Type` header values.
pub struct ContentTypeFilter {
    type_: Option<mime::Name<'static>>,
    subtype: Option<mime::Name<'static>>,
    suffix: Option<mime::Name<'static>>,
}

impl ContentTypeFilter {
    pub fn new(
        type_: Option<mime::Name<'static>>,
        subtype: Option<mime::Name<'static>>,
        suffix: Option<mime::Name<'static>>,
    ) -> Self {
        Self {
            type_,
            subtype,
            suffix,
        }
    }
}

/// Request payload json parser that resolves to a deserialized `T` value.
///
/// Returns error:
///
/// * content type is not `application/json`
/// * content length is greater than 256k
///

Review comment (suggestion):
I don't think it is convenient to use struct with lots of optional fields like that.

I think it might be better if user would be able to supply `mime::Mime` rather than allowing that accurate checks.
On side note it might be better if user could provide function that takes `mime::Mime` and returns whether it should be treated as json or not.

Code after:
    }

    /// Set predicate for allowed content types
    pub fn content_type<F>(&mut self, predicate: F) -> &mut Self
    where
        F: Fn(mime::Mime) -> bool + 'static,
    {
        self.content_type = Some(Box::new(predicate));
        self
    }
}

impl<S> Default for JsonConfig<S> {
    fn default() -> Self {
        JsonConfig {
            limit: 262_144,
            ehandler: Rc::new(|e, _| e.into()),
            content_type: None,
        }
    }
}

/// Request payload json parser that resolves to a deserialized `T` value.
///
/// Returns error:
///
/// * content type is not `application/json`
///   (unless specified in [`JsonConfig`](struct.JsonConfig.html))
/// * content length is greater than 256k
///
/// # Server example
///
/// ```rust
/// # extern crate actix_web;
/// # extern crate futures;
/// # #[macro_use] extern crate serde_derive;
/// use actix_web::{AsyncResponder, Error, HttpMessage, HttpRequest, HttpResponse};
/// use futures::future::Future;
///
/// #[derive(Deserialize, Debug)]
/// struct MyObj {
///     name: String,
/// }
///
/// fn index(mut req: HttpRequest) -> Box<Future<Item = HttpResponse, Error = Error>> {
///     req.json()                   // <- get JsonBody future
///        .from_err()
///        .and_then(|val: MyObj| {  // <- deserialized value
///            println!("==== BODY ==== {:?}", val);
///            Ok(HttpResponse::Ok().into())
///        }).responder()