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 FromRequestParts for Language { type Rejection = (StatusCode, &'static str); async fn from_request_parts(parts: &mut Parts, _: &S) -> Result { parts.extensions.get::().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 }