\usepackage{rust}
Compilez du LaTeX en PDF depuis Rust avec l'API REST FormaTeX. reqwest asynchrone + tokio : aucune installation de TeX Live, aucun binaire à embarquer.
\section{Pourquoi Rust}
Le client asynchrone de reqwest s'intègre naturellement au runtime de Tokio. Compilez plusieurs documents en parallèle sans complexité supplémentaire.
Votre binaire Rust reste petit : pas de TeX Live, pas d'apt install texlive-full. FormaTeX gère entièrement l'environnement de compilation.
Le type Result de Rust s'associe bien à l'API FormaTeX. Convertissez les erreurs HTTP en erreurs métier au niveau du typage, sans mauvaise surprise à l'exécution.
\section{Dependencies}
[dependencies] reqwest = { version = "0.12", features = ["json"] } tokio = { version = "1", features = ["full"] } serde_json = "1" serde = { version = "1", features = ["derive"] } # For Axum integration axum = "0.7" bytes = "1"
\section{Démarrage rapide}
L'exemple ci-dessous compile un document LaTeX minimal avec reqwest et écrit le PDF obtenu sur le disque. Lisez votre clé API depuis l'environnement avec std::env::var("FORMATEX_API_KEY") .
use reqwest::Client;
use serde_json::json;
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("FORMATEX_API_KEY")?;
let latex = r#"\documentclass{article}
\usepackage{amsmath}
\begin{document}
Hello from Rust! $E = mc^2$
\end{document}"#;
let client = Client::new();
let response = client
.post("https://api.formatex.io/api/v1/compile")
.header("X-API-Key", &api_key)
.json(&json!({ "latex": latex, "engine": "pdflatex" }))
.send()
.await?;
if !response.status().is_success() {
let body = response.text().await?;
return Err(format!("API error: {body}").into());
}
let pdf = response.bytes().await?;
fs::write("output.pdf", &pdf)?;
println!("PDF saved to output.pdf");
Ok(())
}\section{Gestionnaire Axum}
Enregistrez un AppState partagé auprès de votre routeur Axum et montez compile_handler sur la route de votre choix. Le gestionnaire accepte un corps JSON avec source et un engine facultatif, puis renvoie les octets du PDF directement au client.
use axum::{
body::Bytes,
extract::State,
http::{HeaderMap, StatusCode},
response::{IntoResponse, Response},
Json,
};
use reqwest::Client;
use serde::Deserialize;
#[derive(Clone)]
pub struct AppState {
pub http: Client,
pub api_key: String,
}
#[derive(Deserialize)]
pub struct CompileRequest {
pub source: String,
#[serde(default = "default_engine")]
pub engine: String,
}
fn default_engine() -> String {
"pdflatex".to_string()
}
pub async fn compile_handler(
State(state): State<AppState>,
Json(body): Json<CompileRequest>,
) -> Result<Response, (StatusCode, String)> {
let res = state
.http
.post("https://api.formatex.io/api/v1/compile")
.header("X-API-Key", &state.api_key)
.json(&serde_json::json!({
"latex": body.source,
"engine": body.engine,
}))
.send()
.await
.map_err(|e| (StatusCode::BAD_GATEWAY, e.to_string()))?;
if !res.status().is_success() {
let msg = res.text().await.unwrap_or_default();
return Err((StatusCode::UNPROCESSABLE_ENTITY, msg));
}
let pdf: Bytes = res
.bytes()
.await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
let mut headers = HeaderMap::new();
headers.insert("Content-Type", "application/pdf".parse().unwrap());
headers.insert(
"Content-Disposition",
"attachment; filename=output.pdf".parse().unwrap(),
);
Ok((headers, pdf).into_response())
}\section{Authentication}
Stockez votre clé API dans l'environnement, sans jamais l'écrire en dur dans les fichiers source. Lisez-la au démarrage et échouez immédiatement si elle est absente :
// Fail fast at startup let api_key = std::env::var( "FORMATEX_API_KEY" ).expect( "FORMATEX_API_KEY not set" );
.env avec la crate dotenvy pendant le développement local. X-API-Key: <key> .\section{Reference}
| Champ | Type | Requis | Description |
|---|---|---|---|
| latex | string | Oui | Code source LaTeX complet sous forme de chaîne |
| engine | string | Non | Moteur à utiliser. Par défaut : "pdflatex". Options : pdflatex, xelatex, lualatex, latexmk |
POST https://api.formatex.io/api/v1/compile : renvoie les octets bruts du PDF en cas de succès ( 200), ou une erreur JSON en cas d'échec (422/ 401).
\section{Gestion des erreurs}
Vérifiez response.status().is_success() avant de lire le corps. Convertissez les erreurs HTTP en votre propre type d'erreur pour une propagation propre :
200 : octets bruts du PDF. À lire avec response.bytes().await? .422 : erreur de compilation LaTeX. Le corps JSON contient un champ error avec un extrait du journal TeX.401 : clé API invalide ou manquante.\section{Autres SDK}
\end{rust}
Obtenez votre clé API et générez des PDF depuis Rust en quelques minutes, sans TeX Live.