relay_server/extractors/
mime.rs

1use std::fmt;
2use std::ops::Deref;
3
4use axum::extract::FromRequestParts;
5use axum::http::request::Parts;
6use axum::http::{StatusCode, header};
7use axum::response::IntoResponse;
8
9use crate::utils::ApiErrorResponse;
10
11#[derive(Clone, Debug)]
12pub struct Mime(mime::Mime);
13
14impl fmt::Display for Mime {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        self.0.fmt(f)
17    }
18}
19
20impl Deref for Mime {
21    type Target = mime::Mime;
22
23    fn deref(&self) -> &Self::Target {
24        &self.0
25    }
26}
27
28#[derive(Debug, thiserror::Error)]
29#[error(transparent)]
30pub struct MimeError(mime::FromStrError);
31
32impl IntoResponse for MimeError {
33    fn into_response(self) -> axum::response::Response {
34        (
35            StatusCode::BAD_REQUEST,
36            ApiErrorResponse::from_error(&self.0),
37        )
38            .into_response()
39    }
40}
41
42impl<S: Send + Sync> FromRequestParts<S> for Mime {
43    type Rejection = MimeError;
44
45    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
46        let mime = parts
47            .headers
48            .get(header::CONTENT_TYPE)
49            .and_then(|v| v.to_str().ok())
50            .unwrap_or("")
51            .parse()
52            .map_err(MimeError)?;
53
54        Ok(Self(mime))
55    }
56}