Aller au contenu
Rust

Rust i18n

Il n'existe pas de crate Better I18N. Un service Rust lit le même JSON du CDN que n'importe quel SDK : reqwest et serde_json suffisent, et les nouveaux textes arrivent sans recompilation.

Setup

Utiliser Better I18N depuis Rust

Ajouter les crates HTTP et JSON

reqwest et serde_json suffisent — il n'y a aucun crate Better I18N à installer.

Cargo.toml
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }

Récupérer un namespace

Le CDN sert un fichier JSON par namespace et par langue, et répond toujours 200.

src/i18n.rs
use std::collections::HashMap;

/// The CDN serves one JSON file per namespace, per locale:
///   https://cdn.better-i18n.com/{org}/{project}/{locale}/{namespace}.json
/// It always answers 200 — an unknown locale returns `{}` rather than an error.
pub async fn fetch_messages(
    locale: &str,
    namespace: &str,
) -> reqwest::Result<HashMap<String, serde_json::Value>> {
    let url = format!(
        "https://cdn.better-i18n.com/your-org/your-project/{locale}/{namespace}.json"
    );

    reqwest::get(&url).await?.json().await
}

Rafraîchir en arrière-plan

Mettez la map en cache dans le processus et relisez-la toutes les 60 secondes, comme le max-age du CDN.

src/main.rs
use std::time::Duration;

// Cache in process and re-read on an interval: the CDN sets
// `Cache-Control: max-age=60`, so a 60s refresh matches it exactly.
tokio::spawn(async move {
    let mut ticker = tokio::time::interval(Duration::from_secs(60));
    loop {
        ticker.tick().await;
        if let Ok(next) = fetch_messages("en", "common").await {
            *messages.write().await = next;
        }
    }
});
Capabilities

Ce que gagnent les services Rust

Aucun SDK requis — et aucun crate Rust n'existe, donc rien à attendre
Du JSON simple en HTTPS, analysé avec serde_json
Fonctionne avec axum, actix-web, Rocket ou un simple binaire
Les nouveaux textes arrivent en 60 secondes environ, sans recompilation
L'API REST couvre tout ce que le CDN ne couvre pas
Coexiste avec rust-i18n si vous l'utilisez déjà pour vos catalogues locaux
Example

Un handler axum qui lit les messages du CDN

Les messages vivent derrière un RwLock et sont rafraîchis par un timer.

use axum::{extract::State, routing::get, Json, Router};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;

type Messages = Arc<RwLock<HashMap<String, serde_json::Value>>>;

async fn greeting(State(messages): State<Messages>) -> Json<serde_json::Value> {
    let messages = messages.read().await;

    let hello = messages
        .get("greeting.hello")
        .and_then(|v| v.as_str())
        .unwrap_or("Hello");

    Json(serde_json::json!({ "message": hello }))
}

#[tokio::main]
async fn main() {
    let messages: Messages = Arc::new(RwLock::new(
        fetch_messages("en", "common").await.unwrap_or_default(),
    ));

    let app = Router::new()
        .route("/greeting", get(greeting))
        .with_state(messages);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Autres frameworks

Get started

Localisez votre service Rust

Créez un projet, publiez votre première langue et lisez-la depuis Rust en HTTPS.