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
pub struct JsonBody {
    pub body: serde_json::Map<String, serde_json::Value>,
}

impl JsonBody {
    pub fn field<T: serde::de::DeserializeOwned>(
        &self,
        field: &str,
    ) -> serde_json::Result<Option<T>> {
        match self.body.get(field) {
            Some(v) => Ok(serde_json::from_value(v.clone())?),
            None => Ok(None),
        }
    }
}

pub trait JsonBodyExt {
    fn json_body(&self) -> serde_json::Result<JsonBody>;
}

impl JsonBodyExt for http::Request<bytes::Bytes> {
    fn json_body(&self) -> serde_json::Result<JsonBody> {
        // TODO: check if content type is application/json
        Ok(JsonBody {
            body: serde_json::from_slice(self.body())?,
        })
    }
}