staxman-old/src/http/accept.rs

69 lines
1.6 KiB
Rust

use axum::{
async_trait,
extract::FromRequestParts,
http::{
header::{HeaderValue, ACCEPT},
request::Parts,
StatusCode,
},
};
/// Extractor for the Accept header
pub struct ExtractAccept(pub HeaderValue);
#[async_trait]
impl<S> FromRequestParts<S> for ExtractAccept
where
S: Send + Sync,
{
type Rejection = (StatusCode, &'static str);
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
if let Some(accept) = parts.headers.get(ACCEPT) {
Ok(ExtractAccept(accept.clone()))
} else {
Err((StatusCode::NOT_ACCEPTABLE, "`Accept` header is missing"))
}
}
}
/// Supported content types
pub(super) enum ResponseType {
Html,
Json,
}
/// Parses the Accept header and returns content type to return
pub(super) fn parse_accept(accept: &HeaderValue) -> ResponseType {
let bytes = accept.as_bytes();
if bytes.starts_with(b"application/json") {
return ResponseType::Json;
}
ResponseType::Html
}
#[cfg(test)]
mod tests {
use axum::{
extract::FromRequest,
http::{HeaderValue, Request},
};
use super::*;
#[tokio::test]
async fn test_accept() {
let req = Request::builder()
.header(ACCEPT, "application/json; charset=utf-8")
.body(())
.unwrap();
let extract = ExtractAccept::from_request(req, &()).await.unwrap();
assert_eq!(
extract.0,
HeaderValue::from_static("application/json; charset=utf-8")
);
}
}