44 lines
1.2 KiB
Rust
44 lines
1.2 KiB
Rust
use crate::utils::i18n::{EN, ZH_CN};
|
|
use async_trait::async_trait;
|
|
use axum::{
|
|
extract::{FromRequestParts, Request},
|
|
http::{request::Parts, StatusCode},
|
|
middleware::Next,
|
|
response::Response,
|
|
};
|
|
use std::ops::Deref;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Language(pub String);
|
|
impl Deref for Language {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl<S: Send + Sync> FromRequestParts<S> for Language {
|
|
type Rejection = (StatusCode, &'static str);
|
|
async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
|
|
parts.extensions.get::<Language>().cloned().ok_or((
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
"language context missing",
|
|
))
|
|
}
|
|
}
|
|
|
|
pub async fn language_middleware(mut req: Request, next: Next) -> Response {
|
|
let language = req
|
|
.headers()
|
|
.get("Accept-Language")
|
|
.and_then(|v| v.to_str().ok())
|
|
.and_then(|v| v.split(',').next())
|
|
.map(str::trim)
|
|
.filter(|v| *v == ZH_CN || *v == EN)
|
|
.unwrap_or(ZH_CN)
|
|
.to_string();
|
|
req.extensions_mut().insert(Language(language));
|
|
next.run(req).await
|
|
}
|