Initial commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
use std::sync::Arc;
|
||||
use axum::{
|
||||
extract::{State, Query},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
Json,
|
||||
};
|
||||
|
||||
use crate::application::services::i18n_application_service::I18nApplicationService;
|
||||
use crate::application::dtos::i18n_dto::{LocaleDto, TranslationRequestDto, TranslationResponseDto, TranslationErrorDto};
|
||||
use crate::domain::services::i18n_service::{Locale, I18nError};
|
||||
|
||||
type AppState = Arc<I18nApplicationService>;
|
||||
|
||||
/// Handler for i18n-related API endpoints
|
||||
pub struct I18nHandler;
|
||||
|
||||
impl I18nHandler {
|
||||
/// Gets a list of available locales
|
||||
pub async fn get_locales(
|
||||
State(service): State<AppState>,
|
||||
) -> impl IntoResponse {
|
||||
let locales = service.available_locales().await;
|
||||
let locale_dtos: Vec<LocaleDto> = locales.into_iter().map(LocaleDto::from).collect();
|
||||
|
||||
(StatusCode::OK, Json(locale_dtos)).into_response()
|
||||
}
|
||||
|
||||
/// Translates a key to the requested locale
|
||||
pub async fn translate(
|
||||
State(service): State<AppState>,
|
||||
Query(query): Query<TranslationRequestDto>,
|
||||
) -> impl IntoResponse {
|
||||
let locale = match &query.locale {
|
||||
Some(locale_str) => {
|
||||
match Locale::from_str(locale_str) {
|
||||
Some(locale) => Some(locale),
|
||||
None => {
|
||||
let error = TranslationErrorDto {
|
||||
key: query.key.clone(),
|
||||
locale: locale_str.clone(),
|
||||
error: format!("Unsupported locale: {}", locale_str),
|
||||
};
|
||||
return (StatusCode::BAD_REQUEST, Json(error)).into_response();
|
||||
}
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
match service.translate(&query.key, locale).await {
|
||||
Ok(text) => {
|
||||
let response = TranslationResponseDto {
|
||||
key: query.key,
|
||||
locale: locale.unwrap_or(Locale::default()).as_str().to_string(),
|
||||
text,
|
||||
};
|
||||
(StatusCode::OK, Json(response)).into_response()
|
||||
},
|
||||
Err(err) => {
|
||||
let status = match &err {
|
||||
I18nError::KeyNotFound(_) => StatusCode::NOT_FOUND,
|
||||
I18nError::InvalidLocale(_) => StatusCode::BAD_REQUEST,
|
||||
I18nError::LoadError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
};
|
||||
|
||||
let error = TranslationErrorDto {
|
||||
key: query.key,
|
||||
locale: locale.unwrap_or(Locale::default()).as_str().to_string(),
|
||||
error: err.to_string(),
|
||||
};
|
||||
|
||||
(status, Json(error)).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets all translations for a locale
|
||||
pub async fn get_translations(
|
||||
State(_service): State<AppState>,
|
||||
locale_code: String,
|
||||
) -> impl IntoResponse {
|
||||
let locale = match Locale::from_str(&locale_code) {
|
||||
Some(locale) => locale,
|
||||
None => {
|
||||
return (StatusCode::BAD_REQUEST, Json(serde_json::json!({
|
||||
"error": format!("Unsupported locale: {}", locale_code)
|
||||
}))).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
// This implementation is a bit weird, as we don't have a way to get all translations
|
||||
// We should improve the I18nService to support this
|
||||
(StatusCode::OK, Json(serde_json::json!({
|
||||
"locale": locale.as_str()
|
||||
}))).into_response()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user