Files
Oxicloud/src/interfaces/api/handlers/i18n_handler.rs
T

119 lines
4.1 KiB
Rust
Raw Normal View History

2025-03-17 21:28:08 +01:00
use axum::{
2026-02-14 01:29:34 +01:00
Json,
extract::{Path, Query, State},
2025-03-17 21:28:08 +01:00
http::StatusCode,
response::IntoResponse,
};
2026-02-14 01:29:34 +01:00
use std::sync::Arc;
2025-03-17 21:28:08 +01:00
2026-02-14 01:29:34 +01:00
use crate::application::dtos::i18n_dto::{
LocaleDto, TranslationErrorDto, TranslationRequestDto, TranslationResponseDto,
};
2025-03-17 21:28:08 +01:00
use crate::application::services::i18n_application_service::I18nApplicationService;
2026-02-14 01:29:34 +01:00
use crate::domain::services::i18n_service::{I18nError, Locale};
2025-03-17 21:28:08 +01:00
type AppState = Arc<I18nApplicationService>;
/// Handler for i18n-related API endpoints
pub struct I18nHandler;
impl I18nHandler {
/// Gets a list of available locales
2026-02-14 01:29:34 +01:00
pub async fn get_locales(State(service): State<AppState>) -> impl IntoResponse {
2025-03-17 21:28:08 +01:00
let locales = service.available_locales().await;
let locale_dtos: Vec<LocaleDto> = locales.into_iter().map(LocaleDto::from).collect();
2026-02-14 01:29:34 +01:00
2025-03-17 21:28:08 +01:00
(StatusCode::OK, Json(locale_dtos)).into_response()
}
2026-02-14 01:29:34 +01:00
2025-03-17 21:28:08 +01:00
/// 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_code(locale_str) {
2026-02-14 01:29:34 +01:00
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();
2025-03-17 21:28:08 +01:00
}
},
None => None,
};
2026-02-14 01:29:34 +01:00
2025-03-17 21:28:08 +01:00
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()
2026-02-14 01:29:34 +01:00
}
2025-03-17 21:28:08 +01:00
Err(err) => {
let (status, error_msg) = match &err {
I18nError::KeyNotFound(_) => (StatusCode::NOT_FOUND, err.to_string()),
I18nError::InvalidLocale(_) => (StatusCode::BAD_REQUEST, err.to_string()),
I18nError::LoadError(_) => {
tracing::error!("I18n load error: {}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
"Translation loading error".to_string(),
)
}
2025-03-17 21:28:08 +01:00
};
2026-02-14 01:29:34 +01:00
2025-03-17 21:28:08 +01:00
let error = TranslationErrorDto {
key: query.key,
locale: locale.unwrap_or(Locale::default()).as_str().to_string(),
error: error_msg,
2025-03-17 21:28:08 +01:00
};
2026-02-14 01:29:34 +01:00
2025-03-17 21:28:08 +01:00
(status, Json(error)).into_response()
}
}
}
2026-02-14 01:29:34 +01:00
/// Gets all translations for a locale (Axum-compatible: extracts locale from path)
pub async fn get_translations_by_locale(
State(service): State<AppState>,
Path(locale_code): Path<String>,
) -> impl IntoResponse {
Self::get_translations(State(service), locale_code).await
}
2025-03-17 21:28:08 +01:00
/// 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_code(&locale_code) {
2025-03-17 21:28:08 +01:00
Some(locale) => locale,
None => {
2026-02-14 01:29:34 +01:00
return (
StatusCode::BAD_REQUEST,
Json(serde_json::json!({
"error": format!("Unsupported locale: {}", locale_code)
})),
)
.into_response();
2025-03-17 21:28:08 +01:00
}
};
2026-02-14 01:29:34 +01:00
2025-03-17 21:28:08 +01:00
// 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
2026-02-14 01:29:34 +01:00
(
StatusCode::OK,
Json(serde_json::json!({
"locale": locale.as_str()
})),
)
.into_response()
2025-03-17 21:28:08 +01:00
}
2026-02-14 01:29:34 +01:00
}