iota_rest_api/
content_type.rs1use axum::http::{self, HeaderMap, StatusCode, header};
6use mime::Mime;
7use tap::Pipe;
8
9#[derive(Debug, Clone)]
11pub struct ContentType(pub Mime);
12
13impl ContentType {
14 pub fn from_headers(headers: &HeaderMap) -> Option<Self> {
15 parse_content_type(headers).ok()?.map(Self)
16 }
17}
18
19fn parse_content_type(headers: &HeaderMap) -> Result<Option<Mime>, mime::FromStrError> {
20 let Some(header) = headers
21 .get(header::CONTENT_TYPE)
22 .and_then(|hval| hval.to_str().ok())
23 else {
24 return Ok(None);
25 };
26
27 let mime: Mime = header.parse()?;
28 Ok(Some(mime))
29}
30
31impl<S> axum::extract::FromRequestParts<S> for ContentType
32where
33 S: Send + Sync,
34{
35 type Rejection = (StatusCode, &'static str);
36
37 async fn from_request_parts(
38 parts: &mut http::request::Parts,
39 _: &S,
40 ) -> Result<Self, Self::Rejection> {
41 parse_content_type(&parts.headers)
42 .map_err(|_| (StatusCode::BAD_REQUEST, "invalid Content-Type mime"))?
43 .ok_or((StatusCode::BAD_REQUEST, "Content-Type header missing"))?
44 .pipe(Self)
45 .pipe(Ok)
46 }
47}