Vue d'ensemble
Langage compilé (LLVM), 0-cost abstractions.
Compilé PerformancePourquoi Rust ?
Sécurité mémoire (pas de GC), concurrence "sans peur".
Sécurité ConcurrenceInstallation (rustup)
rustup (Toolchain) et cargo (Build & Packages).
Projet & Cargo.toml
cargo new, [dependencies], crates.io.
Variables & Types Primitifs
let, mut (mutable), i32, f64, bool, char.
Types Composés
struct (objets), Tuples, Arrays [T; N], Slices &[T].
enum & match
Option, Pattern Matching exhaustif.
Fonctions & ContrĂŽle
fn, if (expression), loop, while, for.
đ L'Ownership (PropriĂ©tĂ©)
Concept clé. Pas de "move" implicite. drop.
đ Le Borrowing (Emprunt)
Références & (partagées) et &mut (exclusives).
đ Les Lifetimes (DurĂ©es de vie)
Annotation 'a pour le "Borrow Checker".
Gestion des Erreurs
Result (Ok, Err). Opérateur ?. Pas de try/catch.
Traits (Interfaces)
Définir un comportement partagé (impl Trait for Struct).
Generics (Génériques)
struct Point, fn foo.
IDE & Outils
VS Code + rust-analyzer (LSP), CLion.
đ Python (PyO3 & Maturin)
Créer des modules Python natifs en Rust.
PyO3 MaturinCas d'usages
CLI (ripgrep), Web (Actix), WebAssembly, Embarqué.
WebAssembly CLICheat-sheet (Syntaxe)
Syntaxe de base (let, fn, struct, match).
Pourquoi Rust est excellent pour la crypto
La cryptographie est un domaine oĂč les bugs coĂ»tent cher. Rust apporte : safety mĂ©moire, contrĂŽle fin (allocations, slices, zero-copy), et un Ă©cosystĂšme crypto moderne orientĂ© constant-time / zeroization.
RĂšgle #1 : ne ârĂ©inventeâ jamais un algo/protocole. Utilise des crates auditĂ©es, des schĂ©mas connus, et des modes AEAD (chiffrement + intĂ©gritĂ©).
Primitives vs protocoles
| Niveau | Exemples | Usage |
|---|---|---|
| Primitives | SHA-256, HMAC, X25519, Ed25519, ChaCha20 | Briques de base |
| Schémas | AEAD (ChaCha20-Poly1305, AES-GCM), KDF (HKDF, Argon2) | Combinaisons sûres |
| Protocoles | TLS, Noise, JOSE/JWT, age | Ăchanges complets |
Cas dâusage typiques
- Auth tokens : HMAC/JWT (attention aux pitfalls), cookies signés
- Stockage secret : chiffrement fichier/at-rest, enveloppe (DEK/KEK)
- Secure messaging : AEAD + échange de clés (X25519) + nonce
- API signature : requĂȘtes signĂ©es, webhooks signĂ©s
- Mot de passe : Argon2 + salt + paramÚtres adaptés
Danger : âchiffrerâ sans authentifier (ex: AES-CBC sans MAC) = vulnĂ©rable (malleability/oracles). En pratique : AEAD partout.
Checklist sécurité
- Génération aléatoire : RNG systÚme (pas pseudo maison)
- AEAD : nonce unique, tag dâauth vĂ©rifiĂ©
- Zeroization : effacer les clés en mémoire
- Versioning : format chiffré versionné + paramÚtres stockés
- Tests : vectors connus + tests de non-régression
Crates âgo-toâ (pratiques & modernes)
| Besoin | Crate | Notes |
|---|---|---|
| RNG (OS) | rand, rand_core | Utiliser OsRng |
| Hash | sha2, blake3 | BLAKE3 trĂšs rapide |
| HMAC | hmac | + sha2 |
| AEAD | chacha20poly1305, aes-gcm | AEAD = encrypt+auth |
| Asymétrique | ed25519-dalek, x25519-dalek | Signatures / ECDH |
| Passwords | argon2 | Params + salt |
| Zeroize | zeroize | Effacement mémoire |
| TLS | rustls | Stack TLS moderne |
Conseil : prĂ©fĂšre des crates maintenues, largement utilisĂ©es, et qui sâappuient sur les traits âRustCryptoâ (aead/digest/cipher) quand câest possible.
Cargo.toml (starter pack)
[dependencies]
rand = "0.8"
sha2 = "0.10"
hmac = "0.12"
chacha20poly1305 = "0.10"
x25519-dalek = "2"
ed25519-dalek = "2"
argon2 = "0.5"
zeroize = "1"Rappels de base (types)
- Key : bytes de taille fixe (ex: 32 bytes) â Ă©viter les
String - Nonce : unique par clĂ© (souvent 12 ou 24 bytes selon lâalgo)
- Tag : authentification (vĂ©rifier avant dâaccepter le plaintext)
- Salt : random + stocké en clair (pour KDF/password hashing)
Anti-pattern : nonce rĂ©utilisĂ© avec la mĂȘme clĂ© = catastrophe (rĂ©vĂšle info, casse AEAD). Stocker un compteur/nonce dans le format chiffrĂ©, ou gĂ©nĂ©rer un nonce alĂ©atoire fiable.
Hash (SHA-256) â intĂ©gritĂ© simple
use sha2::{Sha256, Digest};
fn sha256_hex(data: &[u8]) -> String {
let mut hasher = Sha256::new();
hasher.update(data);
let out = hasher.finalize(); // 32 bytes
hex::encode(out)
}Important : un hash ne prouve pas lâauthenticitĂ© (nâimporte qui peut hasher). Pour une signature/âauthâ, utilise HMAC ou une signature asymĂ©trique.
HMAC-SHA256 â signature symĂ©trique (webhooks, tokens)
use hmac::{Hmac, Mac};
use sha2::Sha256;
type HmacSha256 = Hmac;
fn hmac_hex(key: &[u8], msg: &[u8]) -> String {
let mut mac = HmacSha256::new_from_slice(key).expect("key size");
mac.update(msg);
let tag = mac.finalize().into_bytes();
hex::encode(tag)
} Comparaison en âconstant-timeâ
Pour vĂ©rifier une signature, Ă©vite == sur des bytes âsecretsâ (timing side-channel).
use subtle::ConstantTimeEq;
fn ct_eq(a: &[u8], b: &[u8]) -> bool {
a.ct_eq(b).into()
}Pattern webhook signé (canonique)
// cÎté serveur: recalculer HMAC(payload) et comparer au header
fn verify_webhook(secret: &[u8], payload: &[u8], provided_hex: &str) -> bool {
let expected = hmac_hex(secret, payload);
// comparer en bytes si possible
expected.as_bytes().ct_eq(provided_hex.as_bytes()).into()
}TrĂšs bon usage : webhooks, signatures dâAPI, anti-tamper dâun payload.
Chiffrement moderne : AEAD (ChaCha20-Poly1305)
AEAD = confidentialité + intégrité. Si le tag ne valide pas, on rejette. ChaCha20-Poly1305 est performant (software) et trÚs utilisé.
use chacha20poly1305::{
aead::{Aead, KeyInit, OsRng},
ChaCha20Poly1305, Key, Nonce
};
fn encrypt(key_bytes: [u8; 32], plaintext: &[u8]) -> (Vec, [u8; 12]) {
let cipher = ChaCha20Poly1305::new(Key::from_slice(&key_bytes));
let nonce = ChaCha20Poly1305::generate_nonce(&mut OsRng); // 12 bytes
let ciphertext = cipher.encrypt(&nonce, plaintext)
.expect("encryption failure!");
(ciphertext, nonce.into())
}
fn decrypt(key_bytes: [u8; 32], ciphertext: &[u8], nonce12: [u8; 12]) -> Option> {
let cipher = ChaCha20Poly1305::new(Key::from_slice(&key_bytes));
let nonce = Nonce::from_slice(&nonce12);
cipher.decrypt(nonce, ciphertext).ok()
} Ajouter des âassociated dataâ (AAD)
AAD = données non chiffrées mais authentifiées (ex: id user, version, header).
use chacha20poly1305::aead::{Aead, Payload};
fn encrypt_with_aad(cipher: &chacha20poly1305::ChaCha20Poly1305,
nonce: &chacha20poly1305::Nonce,
plaintext: &[u8],
aad: &[u8]) -> Vec {
cipher.encrypt(nonce, Payload { msg: plaintext, aad })
.expect("encrypt")
} Format conseillé : version | algo | nonce | ciphertext (tout sérialisé), pour permettre rotations, migrations et compat future.
Stratégie de clés (enveloppe)
- DEK (data key) : chiffre tes données (AEAD)
- KEK (key key) : chiffre la DEK (KMS/HSM/secret manager)
- Rotation : on rotate KEK sans rechiffrer toutes les données
Signatures : Ed25519 (authenticité + non-répudiation)
use ed25519_dalek::{SigningKey, VerifyingKey, Signature, Signer, Verifier};
use rand_core::OsRng;
fn sign_and_verify(msg: &[u8]) -> bool {
let sk = SigningKey::generate(&mut OsRng);
let vk: VerifyingKey = sk.verifying_key();
let sig: Signature = sk.sign(msg);
vk.verify(msg, &sig).is_ok()
}TrĂšs bon usage : signatures de release, documents, messages, webhooks publics.
Ăchange de clĂ©s : X25519 (ECDH) â clĂ© partagĂ©e
Pattern classique : 2 parties dérivent un secret partagé, puis utilisent une KDF (HKDF) pour produire une clé AEAD.
use x25519_dalek::{EphemeralSecret, PublicKey};
use rand_core::OsRng;
fn derive_shared() -> [u8; 32] {
let alice_secret = EphemeralSecret::random_from_rng(OsRng);
let alice_pub = PublicKey::from(&alice_secret);
let bob_secret = EphemeralSecret::random_from_rng(OsRng);
let bob_pub = PublicKey::from(&bob_secret);
let alice_shared = alice_secret.diffie_hellman(&bob_pub);
let bob_shared = bob_secret.diffie_hellman(&alice_pub);
// Ils doivent ĂȘtre identiques
assert_eq!(alice_shared.as_bytes(), bob_shared.as_bytes());
*alice_shared.as_bytes()
}Attention : le âshared secretâ brut ne doit pas ĂȘtre utilisĂ© tel quel comme clĂ© AEAD. Il faut une KDF (HKDF) + context (salt/info).
Protocole type âsecure messageâ (simple & solide)
- Key agreement : X25519 (ou clé pré-partagée)
- KDF : HKDF(shared, salt, info) â key32
- AEAD : ChaCha20-Poly1305(key32, nonce unique, aad)
- Format : version + nonce + ciphertext (+ meta)
- VĂ©rif : Ă©chec AEAD â rejeter sans dĂ©tail
Objectif : âencrypt-then-authenticateâ dĂ©jĂ intĂ©grĂ© par AEAD. Moins de dĂ©cisions = moins dâerreurs.
Zéroisation & secrets
use zeroize::Zeroize;
fn handle_secret(mut key: [u8; 32]) {
// ... usage
key.zeroize(); // efface en mémoire
}PiÚges majeurs (à éviter absolument)
- Nonces rĂ©utilisĂ©s (mĂȘme clĂ©) : casse la sĂ©curitĂ© dâAEAD
- Homemade crypto : modes custom, padding custom, PRNG custom
- Logs : ne jamais logger clés, plaintext sensibles, tokens
- Erreurs trop bavardes : âtag invalidâ vs âpadding invalidâ peut aider un attaquant
- Mauvaises KDF : utiliser un hash direct au lieu dâArgon2/HKDF
- Comparaison non-CT : timing leak sur MAC/signature
Hardening (niveau pro)
| ContrĂŽle | Action | But |
|---|---|---|
| Key rotation | Versionner le format + IDs de clés | Migration maßtrisée |
| Secret storage | Vault/KMS + politiques | RĂ©duire lâexposition |
| Fuzzing | cargo fuzz sur parsers | Robustesse formats |
| Audit deps | cargo audit + lock | CVEs |
| Tests vectors | Vectors officiels | Correctness |
Rappel : la crypto est aussi une affaire dâarchitecture (gestion des clĂ©s, rotation, logs, erreurs), pas seulement du code.
Ce quâon met derriĂšre âLangChainâ en Rust
Dans lâĂ©cosystĂšme Rust, lâidĂ©e âLangChainâ = orchestration (prompts, tools, mĂ©moire, chains/agents) + connecteurs (LLM/embeddings) + outils (HTTP, DB, RPC blockchain). Tu branches ensuite des âtoolsâ on-chain (JSON-RPC, indexer, explorer, etc.) et lâagent agit.
Pattern clĂ© : LLM = âcerveauâ (raisonnement, plan) ; Rust = âmusclesâ (I/O, parsing, crypto, perf) ; Blockchain = âsource de vĂ©ritĂ©â (Ă©vĂ©nements, Ă©tats, transactions).
Architecture type (Agent + Tools)
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â App Rust (service) â
â - ObservabilitĂ© / logs / rate-limit / retries â
â - Scheduler (cron, stream) â
â â
â âââââââââââââââââ âââââââââââââââââââââââââââââââââ â
â â Agent/Chain â<------>â LLM Provider (OpenAI/OllamaâŠ) â â
â â (langchain-rs) â âââââââââââââââââââââââââââââââââ â
â âââââââââŹââââââââ â
â â tools â
â ââââââââŽââââââââââââââââ â
â â Tool: Ethereum RPC ââââș Reth/Geth/Infura/Alchemy⊠â
â â Tool: Solana RPC ââââș Solana RPC endpoint â
â â Tool: Substrate RPC ââââș Polkadot parachain RPC â
â â Tool: Indexer/DB ââââș Postgres/ClickHouse⊠â
â âââââââââââââââââââââââââ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââExemples âcrypto-monnaiesâ (cas concrets)
- ETH / L2 : surveillance mempool, analyse de tx, dĂ©tection dâanomalies, suivi de contrats
- Solana : suivi dâaccounts, monitoring programmes, dĂ©tection dâevents rapides
- Polkadot / Substrate : suivi dâextrinsics, events runtime, governance
- Bitcoin : suivi UTXO, analyse blocs, rÚgles simples de conformité (sans trading)
Liens docs (URLs)
LangChain Rust (crate) : https://crates.io/crates/langchain-rust
LangGraph (orchestration) : https://github.com/langchain-ai/langgraph
Reth (Ethereum EL client) : https://github.com/paradigmxyz/reth
Reth docs/site : https://reth.rs/
Lighthouse (ETH consensus) : https://github.com/sigp/lighthouse
Lighthouse book : https://lighthouse-book.sigmaprime.io/
Solana - Rust programs docs : https://solana.com/docs/programs/rust
Anchor (Solana framework) : https://www.anchor-lang.com/
Substrate (Polkadot SDK docs) : https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html
ink! (Rust smart contracts) : https://use.ink/docs/Note : on parle ici dâingĂ©nierie (outillage, monitoring, intĂ©gration), pas de âconseils dâinvestissementâ.
Protocoles / APIs (niveau pratique)
| ĂcosystĂšme | Protocole / API | Ă quoi ça sert |
|---|---|---|
| Ethereum | JSON-RPC (eth_getLogs, eth_call, eth_getBlockâŠ) | Lire Ă©tat / logs / tx |
| Ethereum (clients) | Engine API (EL â CL) | Coordination execution/consensus (nĆuds) |
| Solana | RPC (accounts, signatures, logs) | Lire comptes / instructions / events |
| Substrate | RPC + events runtime | Lire extrinsics / events / storage |
Les âprotocolesâ blockchain (concepts)
- Consensus : PoW, PoS, BFT-style (finalité, forks, reorgs)
- ModĂšle dâexĂ©cution : comptes (Ethereum/Solana) vs UTXO (Bitcoin)
- Finalité : probabiliste vs déterministe (impact sur alerting & monitoring)
- Smart contracts : EVM, Wasm (ink!/Substrate), Solana programs
Stack Rust typique (service âblockchain intelligenceâ)
- Ingestion: websocket/HTTP RPC (stream logs, blocks)
- Normalisation: parse ABI/events, decode instructions
- Stockage: Postgres / ClickHouse (time-series + analytics)
- Indexation: "address â events" + "contract â topics"
- Agent LLM:
* explain(tx) â "rĂ©sumĂ© humain"
* classify(event) â "risk tag"
* generate(alert) â "message"
- Restitution: dashboard / Slack / webhook / APIMeilleur ROI : utiliser lâagent pour lâanalyse sĂ©mantique / tri / explication, et garder toutes les actions âcritiquesâ (signatures, clĂ©s, transferts) strictement hors LLM.
Exemples dâagents âRust + LLM + on-chainâ
Agent #1 â âOn-chain Investigatorâ (Ethereum)
- Input: hash tx / adresse / bloc
- Tool RPC: récupérer receipt + logs + internal traces (si dispo)
- Tool ABI: décoder events (Transfer, Swap, etc.)
- LLM: produire un résumé + détecter pattern suspect (phishing, approvals massifs, etc.)
- Output: rapport + tags (risk/defi/nft/bridge)
Important : lâagent âexpliqueâ, mais ne âjugeâ pas financiĂšrement. On reste sur de la classification technique.
Agent #2 â âContract Watcherâ (Solana / Anchor)
- Stream logs programmes (adresse programme)
- Décoder instructions / accounts
- LLM: dĂ©crire lâaction en langage naturel + gĂ©nĂ©rer une alerte lisible
- Rate-limit + dedup + anti-spam
Agent #3 â âSubstrate Governance Briefâ
- Lire events governance / referenda
- LLM: synthĂšse + points de friction + changements
- Sortie: note quotidienne + changelog
Smart contracts en Rust : 2 mondes majeurs
| ĂcosystĂšme | Rust | Runtime |
|---|---|---|
| Polkadot/Substrate | ink! (Rust eDSL) | Wasm (contracts) |
| Solana | Programs en Rust (souvent via Anchor) | Solana runtime |
Exemples de projets
- Token : mint/burn/transfer + contrĂŽles dâaccĂšs
- Escrow : dépÎt/retrait conditionnel + time locks
- NFT : mint + metadata + royalties (selon chain)
- Oracle adapter : lecture dâun feed + vĂ©rification signatures
Les smart contracts sont irréversibles : audit, tests, fuzzing, et revues sont indispensables.
Comment un LLM aide réellement (sans danger)
- Générer du boilerplate (structures, handlers, events)
- Créer des tests (scénarios, edge cases)
- Expliquer un diff / une vulnĂ©rabilitĂ© (reentrancy-like, auth, overflowâŠ)
- Produire une doc technique et des README propres
Pattern safe : LLM propose â CI teste â humain valide â audit/outils statiques â merge.
Snippet : âToolâ RPC Ethereum (pseudo-code Rust)
IdĂ©e : un tool âget_logsâ appelĂ© par lâagent.
use serde_json::json;
async fn eth_get_logs(rpc_url: &str, from: &str, to: &str, address: &str, topic0: &str) -> anyhow::Result {
let client = reqwest::Client::new();
let payload = json!({
"jsonrpc":"2.0",
"id":1,
"method":"eth_getLogs",
"params":[{
"fromBlock": from,
"toBlock": to,
"address": address,
"topics": [topic0]
}]
});
let res = client.post(rpc_url).json(&payload).send().await?.json().await?;
Ok(res)
} Snippet : âToolâ Solana (concept)
// Concept : appeler RPC "getSignaturesForAddress" puis "getTransaction"
// (en pratique via une lib client Solana ou JSON-RPC brut)
async fn solana_get_tx(rpc_url: &str, signature: &str) -> anyhow::Result {
// POST JSON-RPC ... "getTransaction"
todo!()
} Pattern : Agent = routing + outils
enum ToolCall {
EthGetLogs { from: String, to: String, addr: String, topic0: String },
EthGetTx { hash: String },
SolGetTx { sig: String },
Summarize { json: String },
}
async fn run_tool(call: ToolCall) -> anyhow::Result {
match call {
ToolCall::EthGetLogs{..} => { /* RPC */ Ok("...json...".into()) }
ToolCall::EthGetTx{..} => { /* RPC */ Ok("...json...".into()) }
ToolCall::SolGetTx{..} => { /* RPC */ Ok("...json...".into()) }
ToolCall::Summarize{json}=> { /* LLM */ Ok("résumé".into()) }
}
} Bon design : les tools renvoient du JSON âpropreâ, et le LLM ne fait que lâinterprĂ©ter / rĂ©sumer / classifier.
Sécurité : rÚgles non négociables
- Jamais de clé privée dans un prompt / logs / DB
- Signer les tx hors LLM (HSM/KMS/Hardware wallet / module dédié)
- Valider strictement toutes entrées (addresses, chainId, montants, decimals)
- Limiter lâagent : allowlist dâactions + budgets + rate limits
- ObservabilitĂ© : traces, replay, audit trail, âwhyâ de lâagent
Anti-pattern : âLLM dĂ©cide et signe une transactionâ. Ă proscrire. Pattern safe : LLM propose un plan â humain/Policy Engine valide â composant signe.
PiÚges techniques (blockchain réel)
- Reorgs : une transaction âconfirmĂ©eâ peut ĂȘtre rĂ©organisĂ©e (selon rĂ©seau/finalitĂ©)
- Rate limits : RPC publics limitent (prévoir cache + backoff)
- DĂ©codage ABI : topics/logs incomplets sans ABI â prĂ©voir registry/cache
- Tokens : decimals, approvals, âinfinite allowanceâ â source dâabus
- Bridges : Ă©vĂ©nements cross-chain complexes â prĂ©fĂ©rer indexers/attestations
Bonnes pratiques âprodâ
| Besoin | Solution | But |
|---|---|---|
| Robustesse | Retries + backoff + timeouts | Service stable |
| Coûts | Cache réponses + indexer local | Moins de RPC |
| Qualité | Golden datasets + tests régression | Résumés fiables |
| Confiance | Explainability + logs structurés | Audit trail |
Tip : pour Ethereum, un nĆud Rust (ex: Reth) en local te donne un contrĂŽle total + latence faible, et tu peux brancher ton âagentâ dessus via JSON-RPC.
Ce quâon attend dâun âbon IDE Rustâ
- Analyse sémantique (goto def, rename safe, diagnostics) via rust-analyzer ou équivalent.
- Intégration Cargo (features, workspaces, targets, profiles).
- Debug natif (LLDB) + watch, call stack, breakpoints conditionnels.
- Tests (cargo test, test explorer, filtres, rerun rapide).
- Perf : profiler, flamegraphs (selon IDE / plugins), et au minimum ârelease buildâ facile.
Choix pragmatique : pour 80% des devs â VS Code + rust-analyzer (lĂ©ger) ou RustRover (tout-en-un). Pour le terminal â Helix ou Neovim + LSP.
La base âtoolchainâ (commune Ă tous)
# Toolchain Rust
rustup update
rustup component add rustfmt clippy
# (Optionnel) toolchain spécifique au projet
rustup override set stable
# Vérifier
rustc -V
cargo -VComparatif rapide
| IDE | Points forts | Quand le choisir |
|---|---|---|
| RustRover (JetBrains) | UX IDE complĂšte, refactorings, debug intĂ©grĂ© | Projet pro / âje veux tout dans lâIDEâ |
| VS Code + rust-analyzer | Léger, ultra populaire, trÚs bon LSP | Polyglotte, remote, dev rapide |
| IntelliJ IDEA + Rust plugin | ĂcosystĂšme JetBrains + multi-langage | Monorepo / stack Java/Kotlin + Rust |
| CLion + Rust | Excellent debug natif / C/C++ + Rust | Interop Rust â C/C++ / systĂšmes |
| Helix (terminal) | Tree-sitter + LSP âsimpleâ, rapide | SSH/tmux, minimal mais efficace |
| Neovim (terminal) | Ultra custom (LSP, DAP, plugins) | Power user, config âsur-mesureâ |
RĂšgle dâor : quel que soit lâIDE, câest la âloopâ check â test â clippy â fmt qui te donne la qualitĂ© et la vĂ©locitĂ©.
Top IDEs (marché) + liens officiels
RustRover (JetBrains) :
- Site : https://www.jetbrains.com/rust/
- Download : https://www.jetbrains.com/rust/download/
- Help/Install: https://www.jetbrains.com/help/rust/installation-guide.html
VS Code + rust-analyzer :
- Rust in VS Code (doc) : https://code.visualstudio.com/docs/languages/rust
- rust-analyzer (manual): https://rust-analyzer.github.io/manual.html
- Extension marketplace : https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer
- Debugger CodeLLDB : https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb
IntelliJ IDEA + Rust :
- IntelliJ Rust plugin (doc): https://www.jetbrains.com/help/idea/rust-plugin.html
- Plugin (repo) : https://github.com/intellij-rust/intellij-rust
CLion (JetBrains) :
- Site : https://www.jetbrains.com/clion/
Helix (terminal) :
- Site : https://helix-editor.com/
- Docs : https://docs.helix-editor.com/
Neovim (terminal) :
- Site : https://neovim.io/Configuration âminimum viableâ par IDE
- Installer rustup +
rustfmt/clippy(commun) - Activer rust-analyzer (VS Code / Helix / Neovim) ou support intégré (RustRover/JetBrains)
- Configurer le debugger (LLDB) : CodeLLDB (VS Code) / intégré JetBrains
- Raccourcis Cargo :
check,test,clippy,fmt - Workspace : ouvrir Ă la racine (Cargo.toml principal)
Astuce : si tu bosses sur remote (serveur/WSL), VS Code + Remote est souvent imbattable; sinon RustRover donne une expĂ©rience âluxuryâ trĂšs stable.
Setup âRust proâ (format IDEO-Lab)
- Formatter :
cargo fmt(format-on-save cÎté IDE) - Linter :
cargo clippy(warnings traités comme erreurs si projet exigeant) - Checks rapides :
cargo check(boucle de dev) - Tests :
cargo test+ filtres - Release :
cargo build --release(perf & réalités prod)
# Aliases utiles (shell)
alias ckc='cargo check'
alias tst='cargo test'
alias clp='cargo clippy -- -D warnings'
alias fmt='cargo fmt'
# Exécution ciblée
cargo test module::test_name
cargo test -- --nocaptureParamĂštres rust-analyzer (exemples utiles)
Objectif : diagnostics fiables sur les workspaces, features, et macros.
# VS Code settings.json (extraits)
"rust-analyzer.checkOnSave.command": "clippy",
"rust-analyzer.cargo.allFeatures": true,
"rust-analyzer.procMacro.enable": true,
"rust-analyzer.inlayHints.enable": trueAttention : allFeatures=true peut ralentir de gros workspaces. Si câest lourd, active seulement les features nĂ©cessaires au dev courant.
Workflow Addon Python (PyO3 + Maturin) dans un IDE
Le point clĂ© : ton IDE doit piloter 2 mondes â Cargo (Rust) et la venv Python (pip/pytest). Le âhappy pathâ câest : maturin develop dans la venv, puis pytest.
- Créer le projet :
maturin new mon_ext --bindings pyo3 - Ouvrir la racine dans lâIDE (oĂč il y a
Cargo.toml+pyproject.toml) - Venv Python : configurer lâinterprĂ©teur du projet dans lâIDE
- Build dev : task/run âmaturin developâ (compile & installe dans la venv)
- Tests : task/run âpytestâ (valider lâAPI Python)
# Boucle rapide (terminal intégré IDE)
python -m venv .venv
source .venv/bin/activate
pip install -U pip maturin pytest
maturin develop
pytest -qConfigurer des âRun Configurationsâ (idĂ©es)
| Nom | Commande | But |
|---|---|---|
| Rust: check | cargo check | Feedback instant |
| Rust: clippy | cargo clippy -- -D warnings | Qualité stricte |
| Py: maturin develop | maturin develop | Build addon |
| Py: pytest | pytest -q | Valider API |
| Release wheel | maturin build --release | Distrib |
Tip : garde un répertoire tests/ cÎté Python et des tests Rust unitaires cÎté src/. Tu détectes vite les bugs de conversion (types) + les régressions perf.
Debug Rust âpurâ (bin/tests)
Le plus simple : débugger un binaire ou des tests Rust avec LLDB intégré (JetBrains) ou CodeLLDB (VS Code).
# Debug logique via tests ciblés
cargo test my_module::my_test -- --nocapture
# Debug dâun binaire
cargo run --bin my_tool -- --helpDebug Addon Python (mix Python + Rust)
- Tu lances Python (pytest/script) et tu attaches LLDB au process Python, ou tu dĂ©marres via une config âdebugâ.
- Tu poses des breakpoints dans
src/lib.rs(fonctions#[pyfunction]/#[pymethods]). - Tu rebuild lâextension si nĂ©cessaire (
maturin develop) puis tu relances.
Note : en debug, les symboles sont meilleurs si tu compiles en mode debug (par dĂ©faut). En mode --release, lâoptimisation rend le stepping moins âlisibleâ.
Tests : Rust + Python (double filet)
| Niveau | Commande | Ce que ça couvre |
|---|---|---|
| Unit Rust | cargo test | Algorithmes, edge cases, perf micro |
| API Python | pytest | Conversions, exceptions, ergonomie |
| Qualité | cargo clippy + cargo fmt | Lint + style |
# Reco: commandes âCI-readyâ
cargo fmt -- --check
cargo clippy -- -D warnings
cargo test
# Puis cÎté python (aprÚs maturin develop)
pytest -qTip perf : si tu veux prouver le gain, ajoute un bench (criterion) ou un test perf simple cÎté Python.
Bonnes pratiques (pour ĂȘtre âfluideâ en IDE)
- Workspace clean : ouvrir la racine Cargo; Ă©viter les projets âimbriquĂ©sâ bizarres
- Features : documenter les features Cargo; ne pas activer âall featuresâ inutilement
- Erreurs claires : convertir vers exceptions Python propres (ValueError/TypeError)
- Batch APIs : Ă©viter 1M dâappels PythonâRust; prĂ©fĂ©rer un traitement en lots
- Observabilité : logs structurés cÎté Rust (mais jamais de secrets)
- Reproductible : verrouiller versions (Cargo.lock) + scripts de build
Anti-pattern : dĂ©velopper lâaddon sans tests Python. Tu risques de livrer une extension ârapideâ mais pĂ©nible Ă utiliser (types/erreurs).
Mini check-list âAddon Python prĂȘt prodâ
| Point | OK ? | Notes |
|---|---|---|
| API stable & docstrings | â | signature claire, types simples |
| Erreurs Python propres | â | messages courts + tests |
| CI | â | fmt/clippy/test + build wheel |
| Debuggable | â | symboles en debug, config IDE prĂȘte |
| Bench | â | prouver le gain, Ă©viter placebo |
Choix dâIDE recommandĂ© (simple) : VS Code + rust-analyzer + CodeLLDB pour dĂ©marrer, puis RustRover si tu veux une expĂ©rience âpremiumâ et trĂšs guidĂ©e.
Pourquoi lâavionique est un domaine Ă part
La programmation avionique est soumise Ă des contraintes uniques : safety-critical, temps rĂ©el strict, certification, traçabilitĂ© totale. Un bug logiciel peut avoir des consĂ©quences catastrophiques â le code est traitĂ© comme un composant de sĂ©curitĂ©.
Principe fondamental : on ne cherche pas la âfeature rapideâ, mais la prĂ©visibilitĂ©, la preuve et la robustesse sur des dĂ©cennies.
Civil vs militaire
| Aspect | Civil | Militaire |
|---|---|---|
| Objectif | Sécurité, certification, disponibilité | Performance, résilience, mission-critical |
| Normes | DO-178C, DO-254 | DO-178C + normes défense internes |
| IA embarquée | TrÚs encadrée / limitée | Plus avancée (aide décision, capteurs) |
Contraintes clés du code avionique
- DĂ©terminisme : mĂȘmes entrĂ©es â mĂȘmes sorties â mĂȘmes temps
- Aucune allocation dynamique non maßtrisée
- Pas dâexception non contrĂŽlĂ©e
- Redondance logicielle (diversité de code / langages)
- TraçabilitĂ© : exigence â code â tests â preuves
DiffĂ©rence majeure avec lâIT : ici, le code est souvent plus simple, mais le process est extrĂȘmement lourd.
Architecture avionique moderne
Capteurs (air data, inertiel, radar)
â
âŒ
ââââââââââââââââââââââââââââ
â Calculateurs avioniques â (FCC, FMS, FADEC, ADIRUâŠ)
â - RTOS â
â - Partitionnement â
â - Redondance â
ââââââââââââŹââââââââââââââââ
â Bus avioniques
â (ARINC 429, AFDX, CAN, MIL-STD-1553)
âŒ
ââââââââââââââââââââââââââââ
â Actionneurs & affichage â
â (commandes de vol, MFD) â
ââââââââââââââââââââââââââââCalculateurs & systĂšmes typiques
- FCC â Flight Control Computer
- FMS â Flight Management System
- FADEC â Full Authority Digital Engine Control
- ADIRU â Air Data Inertial Reference Unit
Bus & réseaux avioniques
| Bus | Usage | Caractéristique |
|---|---|---|
| ARINC 429 | Données avioniques | Simple, déterministe |
| AFDX | Avions modernes | Ethernet déterministe |
| MIL-STD-1553 | Militaire | TrĂšs robuste, legacy |
| CAN / CAN-Aero | SystÚmes secondaires | Temps réel simple |
Langages utilisés en avionique
| Langage | Usage | Pourquoi |
|---|---|---|
| Ada | Civil & militaire | Safety, déterminisme, typage fort |
| C déterministe | Bas niveau | ContrÎle total, certifiable |
| C++ (subset) | Avionique moderne | Modularité, OOP contrÎlée |
| Rust (émergent) | Outillage, sécurité | Safety mémoire, fiabilité |
Important : le langage est souvent imposé par le niveau de certification (DAL A à E).
Normes & certifications
- DO-178C â Logiciel avionique (DAL A â E)
- DO-254 â MatĂ©riel Ă©lectronique
- ARP4754A â Architecture systĂšmes
- DO-330 â Qualification des outils
En DAL A, chaque ligne de code doit ĂȘtre justifiĂ©e, testĂ©e, et traçable jusquâĂ lâexigence.
Exemples concrets (avions & systĂšmes)
| Avion | SystĂšme | Description |
|---|---|---|
| Airbus A320/A350 | Commandes de vol électriques | Lois de pilotage, protections enveloppe de vol |
| Boeing 787 | Avionique intégrée | Architecture réseau avancée, calculateurs redondants |
| F-35 | Fusion de capteurs | Radar, IR, EW â vision tactique unifiĂ©e |
| Rafale | SystÚmes de mission | Avionique modulaire, guerre électronique |
Cas emblĂ©matique : le MCAS (737 MAX) a montrĂ© que lâarchitecture et les hypothĂšses sont aussi critiques que le code.
IA embarquée (réalité vs fantasme)
LâIA embarquĂ©e en avionique nâest pas du deep learning libre. Elle est fortement contrainte, explicable et souvent cantonnĂ©e Ă lâaide.
- DĂ©tection dâanomalies capteurs
- Fusion intelligente de données
- Aide à la décision pilote
- Maintenance prédictive
Interdit : une IA non explicable qui prend une décision critique sans supervision humaine (civil).
Futur proche
- More-Electric Aircraft
- Open avionics architectures
- Rust & langages sûrs pour réduire les bugs mémoire
- Digital twins + simulation massive
LâIA devient un copilote logiciel, jamais un pilote autonome en aviation civile.
Sociétés prestigieuses & ressources (URLs)
Constructeurs aéronautiques :
Airbus : https://www.airbus.com/
Boeing : https://www.boeing.com/
Dassault Av. : https://www.dassault-aviation.com/
Ăquipementiers avioniques :
Thales : https://www.thalesgroup.com/
Safran : https://www.safran-group.com/
Collins Aero. : https://www.collinsaerospace.com/
Défense & militaire :
Lockheed Martin : https://www.lockheedmartin.com/
Raytheon : https://www.rtx.com/
Northrop Grumman: https://www.northropgrumman.com/
Normes & références :
DO-178C (RTCA) : https://www.rtca.org/
FAA : https://www.faa.gov/
EASA : https://www.easa.europa.eu/Message clĂ© : lâavionique moderne est lâun des rares domaines oĂč le logiciel est traitĂ© comme une piĂšce mĂ©canique certifiĂ©e.
Pourquoi faire un addon Rust pour Python ?
Objectif : accĂ©lĂ©rer des zones âhotâ Python (CPU bound) en gardant lâergonomie Python. Le code Rust est compilĂ© en module natif (.so/.pyd) importable via import ....
PyO3 = les bindings (types Python â types Rust, macros #[pyfunction], #[pymodule])
Maturin = build + packaging (génÚre une wheel installable par pip, gÚre ABI / tags)
Architecture mentale
Python (app) ââ import mon_ext âââș [module natif .so/.pyd]
â
ââ API Python (fonctions/classes)
â
ââ Rust "core" (perf / safety / threads)
âČ
ââ PyO3 (bridge + GIL + conversions)
âČ
ââ Maturin (build + wheel + publish)Quand câest pertinent (et quand non)
| Cas | Rust addon ? | Notes |
|---|---|---|
| Boucles lourdes / parsing / hashing | â Oui | Gains majeurs (CPU bound) |
| Traitement vectoriel (numpy) | â ïž Ăa dĂ©pend | Parfois numpy suffit; sinon Rust + buffers |
| I/O bound (rĂ©seau, disque) | â Rare | Le bottleneck nâest pas le CPU |
| Concurrence / threads | â Oui | Attention au GIL cĂŽtĂ© Python |
| Interop C/C++ existante | â Oui | Rust âsafe wrapperâ + exposition Python |
RĂšgle dâor : un addon Rust doit viser une fonction stable (API claire), trĂšs sollicitĂ©e, et facilement testable. Sinon, la complexitĂ© du build ne vaut pas le coup.
Protocole âstandardâ (zĂ©ro surprise)
- CrĂ©er le projet : scaffold Maturin (lib cdylib, layout prĂȘt)
- Configurer
Cargo.toml:crate-type, dĂ©pendances PyO3, features - Ăcrire lâAPI : fonctions/classes exposĂ©es (
#[pyfunction],#[pyclass]) - Build local :
maturin develop(installe dans venv) - Tests : pytest + tests Rust si besoin; vérifier edge cases & erreurs
- Build wheel :
maturin build --release - Distrib : publier (PyPI) ou installer wheel interne
Commandes utiles
# 0) Pré-requis
rustup update
python -m venv .venv
source .venv/bin/activate
pip install -U pip maturin
# 1) Scaffold (template PyO3)
maturin new mon_ext --bindings pyo3
# 2) Dev loop : compile + installe dans le venv
cd mon_ext
maturin develop
# 3) Wheel release
maturin build --release
# 4) Installer la wheel générée
pip install target/wheels/mon_ext-*.whlChecklist âCargo.tomlâ (canonique)
[package]
name = "mon_ext"
version = "0.1.0"
edition = "2021"
[lib]
name = "mon_ext"
crate-type = ["cdylib"]
[dependencies]
pyo3 = { version = "0.20", features = ["extension-module"] }
# Optionnel (si tu veux des erreurs propres)
# anyhow = "1"
# thiserror = "1"
[profile.release]
lto = true
codegen-units = 1Pourquoi cdylib ? Câest le type de crate destinĂ© Ă produire une bibliothĂšque dynamique exploitable par Python (via lâextension native).
Structure de repo (propre)
mon_ext/
pyproject.toml # (packaging Python)
Cargo.toml # (packaging Rust)
src/
lib.rs # (exposition PyO3)
tests/
test_api.py # (pytest)
README.mdModule minimal : 2 fonctions + 1 exception
Exemple volontairement ârĂ©alisteâ : validation dâentrĂ©e + erreur explicite.
// src/lib.rs
use pyo3::prelude::*;
use pyo3::exceptions::PyValueError;
/// Somme rapide (exemple simple)
#[pyfunction]
fn add_i64(a: i64, b: i64) -> PyResult {
Ok(a + b)
}
/// Normalise un vecteur (erreur si norme=0)
#[pyfunction]
fn normalize(v: Vec) -> PyResult> {
let norm = v.iter().map(|x| x*x).sum::().sqrt();
if norm == 0.0 {
return Err(PyValueError::new_err("norme nulle"));
}
Ok(v.into_iter().map(|x| x / norm).collect())
}
#[pymodule]
fn mon_ext(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(add_i64, m)?)?;
m.add_function(wrap_pyfunction!(normalize, m)?)?;
Ok(())
} Utilisation Python
# Dans ton venv aprĂšs `maturin develop`
import mon_ext
print(mon_ext.add_i64(40, 2)) # 42
print(mon_ext.normalize([3.0, 4.0])) # [0.6, 0.8]
try:
mon_ext.normalize([0.0, 0.0])
except ValueError as e:
print("Erreur:", e)Pourquoi ça marche âcomme un moduleâ ?
La macro #[pymodule] dĂ©clare le point dâentrĂ©e du module Python. PyO3 sâoccupe de crĂ©er les symboles attendus par lâimport Python.
API design : expose peu, expose propre. Ton addon doit ĂȘtre une âboĂźte noireâ stable : types simples, erreurs Python claires, docstring utile.
Exemples dâaddons typiques (trĂšs demandĂ©s)
| Addon | Pourquoi | API Python |
|---|---|---|
| Fingerprint / Hashing | Dédup, cache keys, signatures rapides | fingerprint(bytes) -> str |
| Parser / tokenizer | Extraction texte, logs, formats custom | tokenize(str) -> list[str] |
| Matching / search | Filtres/regex-like rapides, scoring | match_many(pattern, items) -> list[int] |
| Compression / codecs | Compression streaming CPU bound | compress(bytes) -> bytes |
| Geo / distance | Calculs massifs sur points | haversine(lat1, lon1, lat2, lon2) |
Exemple : Fingerprint (bytes â hex)
use pyo3::prelude::*;
#[pyfunction]
fn fingerprint(data: &[u8]) -> PyResult {
use blake3::Hasher;
let mut h = Hasher::new();
h.update(data);
Ok(h.finalize().to_hex().to_string())
}
#[pymodule]
fn mon_ext(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(fingerprint, m)?)?;
Ok(())
} Exemple : Parser (JSON rapide â struct)
Ici lâidĂ©e est : valider + extraire vite, renvoyer dict ou tuple Python.
use pyo3::prelude::*;
use pyo3::types::PyDict;
use serde::Deserialize;
#[derive(Deserialize)]
struct Event { kind: String, ts: i64 }
#[pyfunction]
fn parse_event(py: Python, s: &str) -> PyResult {
let ev: Event = serde_json::from_str(s)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
let d = PyDict::new(py);
d.set_item("kind", ev.kind)?;
d.set_item("ts", ev.ts)?;
Ok(d.to_object(py))
} Intégration Python propre (API stable)
Ne force pas tes utilisateurs Ă connaĂźtre Rust. Fournis une API Python âclassiqueâ : docstrings, exceptions, types simples, et un module __init__.py ergonomique.
# python/mon_pkg/__init__.py (exemple)
from .mon_ext import fingerprint, parse_event
__all__ = ["fingerprint", "parse_event"]Bench & validation
# tests/test_perf.py (exemple simple)
import time
import mon_ext
def bench():
payload = b"x" * 1024
t0 = time.perf_counter()
for _ in range(200_000):
mon_ext.fingerprint(payload)
return time.perf_counter() - t0Bon pattern : garde Python pour lâorchestration (I/O, glue code) et Rust pour les kernels CPU.
GIL, threads, et âne pas se tirer une balleâ
Python a le GIL : un seul thread Python exécute du bytecode à la fois. Mais ton Rust peut faire du travail CPU en parallÚle si tu libÚres le GIL pendant le calcul.
use pyo3::prelude::*;
#[pyfunction]
fn heavy(py: Python, n: usize) -> PyResult {
// LibĂšre le GIL pendant la zone CPU
let out = py.allow_threads(|| {
(0..n as u64).map(|x| x.wrapping_mul(31)).sum::()
});
Ok(out)
} RÚgle : ne touche pas à des objets Python (PyObject, PyDict, etc.) quand tu es dans allow_threads. Fais ton calcul Rust pur, puis reviens cÎté Python pour produire la sortie.
Types : simple dâabord
Commence par i64, f64, String, Vec<T>, bytes. Passe à des objets Python complexes seulement si nécessaire.
PiĂšges classiques
- ABI / wheels : si tu distribues, vise des wheels compatibles (Linux/macOS/Windows).
- Doc & erreurs : renvoyer des
PyErrpropres (ValueError/TypeError) sinon UX pénible. - API instable : changer les signatures casse les users (versionne proprement).
- Conversion coĂ»teuse : Ă©viter dâaller/retour PythonâRust Ă lâintĂ©rieur dâune boucle.
- GIL misuse : ne manipule pas dâobjets Python hors GIL.
Anti-pattern frĂ©quent : exposer une fonction appelĂ©e 1 million de fois depuis Python, avec des conversions lourdes Ă chaque appel â prĂ©fĂ©rer âbatch APIâ (passer un tableau complet).
Bonnes pratiques (IDEO-Lab grade)
- Expose une API âbatchâ :
process_many(list[...])plutÎt queprocess_one()en boucle - Erreurs explicites : messages courts, typés, testés (pytest)
- Bench systĂ©matique : prouver le gain, sinon ce nâest pas justifiĂ©
- Release profile : LTO + optimisations release
- Versionning : semver; changelog si API évolue
- CI : build wheels + tests (au moins Linux/macOS)
Mini âtemplateâ dâAPI stable
# Python public API (stable)
# - Fonctions pures
# - Entrées simples
# - Sorties simples
# - Exceptions typées
def fingerprint(data: bytes) -> str: ...
def parse_event(json_str: str) -> dict: ...
def process_many(items: list[bytes]) -> list[str]: ...Comparatif synthĂ©tique (vision âarchitecteâ)
| CritĂšre | Rust | C++ | C âdĂ©terministeâ | Java |
|---|---|---|---|---|
| Objectif principal | + Safety + Perf native â systĂšmes sĂ»rs & rapides | + Perf + FlexibilitĂ© â ComplexitĂ© | + DĂ©terminisme + Certif â Contraintes | + ProductivitĂ© + ĂcosystĂšme â GC/Jitter |
| Performance brute | TrĂšs Ă©levĂ©e (proche C/C++) | TrĂšs Ă©levĂ©e (rĂ©fĂ©rence historique) | TrĂšs Ă©levĂ©e (code souvent simple/linĂ©aire) | ĂlevĂ©e (JIT, parfois proche natif) |
| Latence / jitter | TrĂšs bon (pas de GC) â dĂ©pend du design | TrĂšs bon â dĂ©pend du design | Excellent (focus dĂ©terminisme RT) | Variable (GC, warmup JIT) â tuning possible |
| Safety mĂ©moire | Fort (borrow checker, ownership) | Faible â moyen (RAII aide) + UB possible | Faible (discipline + subset + analyse statique) | Fort (runtime + GC, pas dâUB âclassiqueâ) |
| Concurrence | TrĂšs bon (types/ownership) + moins de data races | TrĂšs bon (facile de se tromper) | EncadrĂ©e (prĂ©visible) â contraintes RT | TrĂšs bon (threads + libs + modĂšles) |
| ĂcosystĂšme | Moderne (cargo, crates.io) + DX excellent | Immense (legacy + industrie) â hĂ©tĂ©rogĂšne | SpĂ©cialisĂ© (embarquĂ©/avionique) â niche | TrĂšs vaste (enterprise, frameworks) |
| PortabilitĂ© | TrĂšs bonne (cross-compile) | Bonne â toolchains parfois complexes | TrĂšs bonne (souvent bare-metal) | TrĂšs bonne (JVM) â dĂ©pend runtime |
| Time-to-market | Moyen (apprentissage + rigueur) â qualitĂ© long terme | Moyen â long (complexitĂ© / build) | Long (normes, contraintes, process) | Rapide (frameworks + libs) |
| Niveau difficultĂ© | ĂlevĂ© (ownership, lifetimes) â bugs Ă©vitĂ©s | ĂlevĂ© (templates, UB, build) | Moyen â Ă©levĂ© (discipline, subset, preuves) | Moyen (outillage mature) â tuning JVM parfois requis |
| Idéal pour | Systems sûrs, crypto, tooling | Engines/HPC, temps réel, legacy | Safety-critical, avionique, certif | Backends, services, enterprise |
Lecture rapide : Rust = âC++ avec garde-fous modernesâ ; C dĂ©terministe = âC strict + prĂ©dictibilitĂ©â ; Java = âprod & scale enterprise avec JVMâ.
Rust â avantages / limites
- + Safety mémoire (ownership/borrow) sans GC
- + Tooling (cargo, fmt, clippy, tests, docs)
- + Concurrence plus sûre
- â Courbe (lifetimes/borrow) surtout au dĂ©but
- â Interop/FFI parfois nĂ©cessaire (C libs, systĂšmes)
C++ â avantages / limites
- + Perf & contrĂŽle total (zĂ©ro overhead âsi bien faitâ)
- + ĂcosystĂšme immense (industriel, legacy, libs)
- + Multiparadigme (templates, RAII, etc.)
- â ComplexitĂ© du langage & des builds
- â UB / vulnĂ©rabilitĂ©s si discipline insuffisante
C âdĂ©terministeâ â avantages / limites
Ici âC dĂ©terministeâ = pratique industrielle safety-critical : un subset C + rĂšgles strictes (style, mĂ©moire, allocations, recursion, etc.) pour garantir prĂ©visibilitĂ© et audit.
- + Déterminisme (latence/jitter maßtrisés)
- + Certifiabilité (process + rÚgles + outillage)
- + Simplicité du runtime (souvent bare-metal)
- â ProductivitĂ© (beaucoup de rĂšgles, contraintes)
- â Safety mĂ©moire dĂ©pend de la discipline/outils
Java â avantages / limites
- + Productivité (frameworks, libs, tooling)
- + Scalabilité enterprise (observabilité, ops, standardisation)
- + Performance élevée grùce au JIT
- â GC : latence variable (tuning possible)
- â Moins âbas niveauâ (contrĂŽle mĂ©moire/ABI)
Cas dâusage typiques (et pourquoi)
| Domaine | Langages fréquents | Pourquoi |
|---|---|---|
| Crypto / sécurité | Rust, C/C++ | Perf + contrÎle + libs; Rust apporte safety |
| Embarqué safety-critical | C déterministe, Ada (souvent), parfois C++ subset | Certification, contraintes temps réel, audits |
| Backends / microservices | Java, Rust, (Go, etc.) | ĂcosystĂšme, ops, perf, stabilitĂ© |
| HPC / engines | C++, Rust, C | Perf maximale, SIMD, contrÎle mémoire |
| Trading low-latency | C++, Rust, Java (selon architecture) | Latence, throughput, tuning fin |
Point clĂ© : le langage nâest quâune partie. Le âniveau de risqueâ (safety-critical) impose process, rĂšgles de coding, tests, preuves et audits â parfois plus dĂ©terminants que le choix du langage.
Popularité (lecture réaliste)
La âpopularitĂ©â varie selon lâindicateur : usage industriel, volume GitHub, offres dâemploi, satisfaction dev, etc. En pratique :
- Java : extrĂȘmement prĂ©sent en enterprise (banques, ERP, services).
- C++ : énorme base installée (industrie, engines, HPC, systÚmes).
- C déterministe : trÚs présent dans des niches à forte contrainte (avionique/embarqué).
- Rust : forte croissance (infra, crypto, tooling), adoption progressive en prod.
Signal concret : Rust brille souvent en âsatisfaction dĂ©veloppeurâ, Java/C++ dominent en âbase installĂ©eâ.
ĂcosystĂšmes & tooling (ce qui compte en prod)
| Langage | Build / deps | Qualité / tooling |
|---|---|---|
| Rust | Cargo + crates.io | fmt/clippy/test/docs intégrés |
| C++ | CMake/Conan/vcpkg⊠| TrÚs bon mais hétérogÚne |
| C déterministe | Toolchain vendor | Analyse statique, rÚgles strictes |
| Java | Maven/Gradle | Tooling mature + observabilité JVM |
Difficulté : pourquoi certains galÚrent ?
- Rust : ownership/lifetimes â oblige Ă structurer correctement la mĂ©moire et la concurrence.
- C++ : langage trĂšs vaste + UB + templates â complexitĂ© âcombinatoireâ.
- C dĂ©terministe : pas âdurâ syntaxiquement, mais dur par discipline et contraintes.
- Java : concepts plus simples, mais architecture/performances JVM demandent expérience.
Niveau de difficulté (indicatif)
| Langage | Difficulté | Pourquoi |
|---|---|---|
| Rust | 8/10 | Borrow checker, lifetimes, patterns async |
| C++ | 9/10 | Complexité, UB, build/tooling, modern C++ |
| C déterministe | 7/10 | RÚgles strictes, subset, preuves/tests |
| Java | 5/10 | Langage accessible, complexitĂ© plutĂŽt âsystĂšmeâ |
Performance : âvrai mondeâ
Les micro-benchmarks ne reflĂštent pas toujours la prod. En vrai :
- C++ / Rust excellent contrĂŽle mĂ©moire â perf stable si architecture solide.
- C dĂ©terministe vise dâabord la prĂ©dictibilitĂ© (latence stable) plutĂŽt que âmax perfâ.
- Java peut ĂȘtre trĂšs rapide (JIT), mais latence dĂ©pend GC / tuning / warmup.
Conclusion perf : Rust/C++ gagnent sur le bas niveau; Java gagne souvent sur la productivitĂ©. âC dĂ©terministeâ gagne sur la certifiabilitĂ© et la stabilitĂ© temporelle.
Choisir vite (rĂšgles pratiques)
- Tu veux du natif sĂ»r (rĂ©seau, crypto, tooling) â Rust
- Tu as du legacy / libs industrielles / perf extrĂȘme â C++
- Tu es en safety-critical certifiĂ© (DO-178C, etc.) â C dĂ©terministe (ou Ada selon contexte)
- Tu veux livrer vite avec un Ă©cosystĂšme enterprise â Java
Raccourci : si tu hĂ©sites entre Rust et C++ pour un nouveau projet âsystĂšmeâ, Rust est souvent le meilleur pari long terme (safety + tooling).
Matche âlangage â produitâ (exemples)
| Produit | Meilleur fit | Pourquoi |
|---|---|---|
| Proxy réseau / observabilité | Rust | Perf + sécurité mémoire + async |
| Moteur 3D / simulateur | C++ | ĂcosystĂšme & perf + legacy |
| ContrÎle avionique certifié | C déterministe | Déterminisme + process + audit |
| Plateforme backend enterprise | Java | ĂcosystĂšme + ops + recrutement |
Important : en âC dĂ©terministeâ, le langage est souvent dĂ©fini par la norme/process plus que par un choix âtechnique purâ.
Qu'est-ce que Rust ?
Rust est un langage de programmation **systÚme** (comme C++), développé par Mozilla, axé sur trois objectifs :
- **Performance :** Aussi rapide que C/C++.
- **Sécurité (Mémoire) :** Garanties à la compilation (pas de "segfault", "null pointer"...).
- **Concurrence :** Ăcrire du code multi-threadĂ© "sans peur".
La promesse de Rust est de fournir des "abstractions à coût zéro" (zero-cost abstractions) : des fonctionnalités haut niveau (comme en Python) qui se compilent en code machine aussi optimisé que si vous l'aviez écrit "à la main".
La Compilation (Rust -> LLVM)
Rust est un langage **compilé** (AOT - Ahead-of-Time). Il n'y a pas de machine virtuelle (comme Java) ni d'interpréteur (comme Python).
Le compilateur rustc vérifie la sécurité (via le "Borrow Checker"), puis traduit le code en LLVM IR (Intermediate Representation), qui est ensuite optimisé et compilé en binaire natif (code machine) pour votre OS (Windows, macOS, Linux).
+----------------------+
| main.rs (Votre code) |
+----------------------+
|
| (1. Lancer 'cargo build')
âŒ
+----------------------+
| rustc (Compilateur) |
| (Vérifie l'Ownership) |
+----------------------+
|
| (2. Traduit en)
âŒ
+-----------------------+
| LLVM (Optimisation) |
+-----------------------+
|
| (3. GénÚre)
âŒ
[Binaire Natif (ex: .exe)]
Le ProblĂšme (Le compromis habituel)
Historiquement, les développeurs devaient choisir :
1. Performance (ex: C++) : Rapide, mais gestion manuelle de la mémoire, menant à des "segfaults", des "memory leaks" et des failles de sécurité.
// C++ (Risqué)
void use_data(Config* config) {
// ...
}
Config* c = new Config();
use_data(c);
// (Oups, j'ai oublié de faire 'delete c')
// --> Memory Leak
2. Sécurité (ex: Python, Java) : Gestion automatique de la mémoire (Garbage Collector - GC), mais au détriment de la performance (le GC "pause" le programme) et d'une utilisation mémoire plus élevée.
La Solution (Rust : Sécurité ET Performance)
Rust résout ce dilemme avec son systÚme d'**Ownership (Propriété)**.
Il n'y a **pas de Garbage Collector**. La mémoire est gérée à la **compilation**. Le compilateur suit des rÚgles strictes (voir section 3.x) pour savoir *exactement* quand libérer la mémoire (à la fin de la "portée" du propriétaire).
// Rust (Sûr)
fn use_data(config: &Config) { // (Emprunt)
// ...
}
fn main() {
let c = Config::new(); // (Propriétaire)
use_data(&c);
// (Rust sait que 'c' sort du scope ici)
// (InsÚre automatiquement la libération mémoire)
// --> Pas de 'delete' manuel, pas de GC.
}
Résultat : La vitesse de C++, avec des garanties de sécurité mémoire plus fortes que Java ou Python.
rustup & cargo)1. rustup (Le Gestionnaire)
L'installation se fait via rustup. C'est un gestionnaire de "toolchains" (versions de Rust).
# 1. Installer rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 2. Mettre Ă jour
rustup update
# 3. Changer de version (ex: nightly)
rustup default nightly2. rustc (Le Compilateur)
rustc est le compilateur. (On l'utilise rarement directement).
rustc main.rs
./main3. cargo (Le Couteau Suisse)
cargo est l'outil central : gestionnaire de paquets (crates) ET outil de build. (Ăquivalent de npm/pip + make/webpack).
# 1. Créer un nouveau projet
cargo new mon_projet
# 2. Compiler (en mode debug)
cargo build
# 3. Compiler (optimisé pour la prod)
cargo build --release
# 4. Compiler ET Exécuter
cargo run
# 5. Lancer les tests
cargo test
# 6. Mettre à jour les dépendances
cargo updateCargo.toml (Manifeste)Cargo.toml (Le package.json de Rust)
Ce fichier (format TOML) décrit votre projet, ses métadonnées et ses dépendances.
[package]
name = "mon_projet"
version = "0.1.0"
edition = "2021" # (Version du "langage" Rust)
# Les dépendances (ex: pour un serveur web)
[dependencies]
actix-web = "4"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
# Dépendances de développement (tests, benchmarks)
[dev-dependencies]
criterion = "0.4"crates.io (Le npm de Rust)
L'écosystÚme Rust repose sur des paquets appelés "Crates".
crates.io est le registre public (dépÎt) officiel des crates. (Similaire à PyPI pour Python ou npmjs pour Node.js).
# (Ajouter une dépendance via la ligne de commande)
cargo add serde
# (Cargo.toml est mis Ă jour automatiquement)
Lorsque vous lancez cargo build, Cargo télécharge les versions spécifiées de crates.io, les compile, et les linke à votre projet.
Variables (let, mut, Shadowing)
Les variables sont **immuables (read-only)** par défaut. On doit utiliser mut pour les rendre mutables.
let x: i32 = 5; // Immuable
// x = 6; // Erreur !
let mut y: i32 = 5; // Mutable
y = 6; // OK
// Shadowing (Masquage)
let z = "texte";
let z = z.len(); // OK (z est maintenant un number)Types Primitifs (Scalaires)
Rust est statiquement typĂ©. Le type doit ĂȘtre connu Ă la compilation (souvent infĂ©rĂ©).
// Entiers (signés 'i' et non-signés 'u')
let bits_8: u8 = 1;
let entier: i32 = -10; // (Défaut pour les entiers)
let arch: usize = 0; // (Taille de l'architecture, 32/64 bits)
// Flottants
let flottant: f64 = 3.14; // (Défaut pour les flottants)
// Booléen
let est_vrai: bool = true;
// CaractĂšre (Unicode - 4 bytes)
let c: char = 'đŠ';Tuples
Un "Tuple" est une collection de types différents, de longueur fixe.
let tup: (i32, f64, char) = (500, 6.4, 'a');
// Déstructuration
let (x, y, z) = tup;
// AccĂšs par index
let cinq_cents = tup.0;Arrays & Slices
Array: Longueur fixe, mĂȘme type, sur la Stack.
let arr: [i32; 3] = [1, 2, 3];
let premier = arr[0];Slice: Une "vue" (référence) sur une partie d'un Array (ou Vec).
let slice: &[i32] = &arr[1..3]; // [2, 3]
Structs (Structures)
L'équivalent des "objets" ou "interfaces" pour regrouper des données.
// 1. Définition
struct Utilisateur {
actif: bool,
nom: String,
email: String,
age: u32,
}
// 2. Instanciation
let mut user1 = Utilisateur {
email: String::from("user@mail.com"),
nom: String::from("Alice"),
actif: true,
age: 30,
};
// 3. AccĂšs (notation "point")
user1.nom = String::from("Bob");
// 4. Syntaxe "shorthand"
fn build_user(email: String, nom: String) -> Utilisateur {
Utilisateur {
email, // (shorthand)
nom, // (shorthand)
actif: true,
age: 25,
}
}enum & Pattern Matching (match)Les Enums en Rust sont trĂšs puissants. Ils permettent de dĂ©finir un type qui peut ĂȘtre l'une de plusieurs "variantes". Chaque variante peut contenir des donnĂ©es.
Option est l'Enum le plus célÚbre (pour gérer l'absence de valeur, pas de null en Rust).
// Définition de l'Enum Optionenum Option { None, // Absence de valeur Some(T), // Présence d'une valeur T }
Le Pattern Matching (match) est utilisé pour gérer les Enums. match est **exhaustif** : le compilateur vous force à gérer *tous* les cas possibles.
fn diviser(a: f64, b: f64) -> Option{ if b == 0.0 { Option::None } else { Option::Some(a / b) } } let resultat = diviser(10.0, 2.0); // Option::Some(5.0) let resultat_err = diviser(10.0, 0.0); // Option::None // 'match' force à gérer Some ET None match resultat { Option::Some(valeur) => { println!("Résultat : {}", valeur); } Option::None => { println!("Erreur : Division par zéro !"); } } // 'if let' (si on ne gÚre qu'un cas) if let Some(valeur) = resultat { println!("Résultat : {}", valeur); }
Fonctions (fn)
Syntaxe : fn nom(arg: Type) -> TypeRetour.
Rust utilise des **expressions**. La derniĂšre expression d'une fonction est son retour (sans ;).
// Fonction simple
fn saluer(nom: &str) {
println!("Bonjour, {}!", nom);
}
// Fonction avec retour (typage obligatoire)
fn addition(a: i32, b: i32) -> i32 {
a + b // (Pas de 'return', pas de ';')
// 'return a + b;' est aussi valide (statement)
}
// (Le 'main' est le point d'entrée)
fn main() {
saluer("Monde");
let somme = addition(5, 3);
}Flux de ContrĂŽle
if est une expression (peut retourner une valeur).
let x = 5;
let y = if x == 5 {
10 // (Type i32)
} else {
0 // (Doit ĂȘtre i32 aussi)
};
// Boucle infinie
loop {
println!("Encore !");
break; // (Nécessaire)
}
// Boucle (while)
let mut n = 3;
while n != 0 {
n -= 1;
}
// Boucle (for)
let a = [10, 20, 30];
for element in a {
println!("valeur: {}", element);
}C'est le concept central de Rust. Il permet la sécurité mémoire **sans Garbage Collector**.
Les 3 RĂšgles de l'Ownership :
- Chaque valeur en Rust a un "propriétaire" (Owner).
- Il ne peut y avoir qu'**un seul propriétaire** à la fois.
- Lorsque le propriétaire sort du "scope" (portée,
{}), la valeur est "détruite" (drop) et la mémoire est libérée.
Le "Move" (Déplacement)
Pour les types complexes (sur le "Heap", comme String), assigner à une autre variable **transfÚre la propriété** (un "move").
let s1 = String::from("hello"); // s1 est propriétaire
let s2 = s1; // La propriété est "déplacée" de s1 vers s2
// s1 n'est PLUS VALIDE.
println!("{}, monde !", s1);
// ERREUR A LA COMPILATION:
// "borrow of moved value: `s1`"
// (Le compilateur empĂȘche un 'double free')Note : Les types simples (primitifs, sur la "Stack") sont copiĂ©s (Copy), pas "movĂ©s".
Si le "move" était la seule option, ce serait inutilisable. On peut **"emprunter"** une valeur sans en prendre la propriété, via une **Référence** (&).
Les 2 RĂšgles de l'Emprunt :
- Ă un instant T, vous pouvez avoir :
- Soit une (et une seule) référence **mutable** (
&mut). - Soit *N* références **immuables** (
&).
- Soit une (et une seule) référence **mutable** (
- Les rĂ©fĂ©rences doivent toujours ĂȘtre valides (cf. Lifetimes).
// 's' est une référence (emprunt)
fn calculer_longueur(s: &String) -> usize {
s.len()
// 's' n'est pas propriétaire,
// il ne 'drop' rien Ă la fin.
}
fn modifier_string(s: &mut String) {
s.push_str(", monde");
}
let mut s1 = String::from("hello");
// 1. Emprunt immuable
let len = calculer_longueur(&s1); // OK
// 2. Emprunt mutable
modifier_string(&mut s1); // OK
// 3. Conflit (interdit)
let r1 = &mut s1; // (Emprunt mutable)
let r2 = &s1; // (Emprunt immuable)
// ERREUR: "cannot borrow `s1` as immutable
// because it is also borrowed as mutable"Les "Lifetimes" ('a, 'b) sont la syntaxe que le "Borrow Checker" utilise pour garantir que les références (emprunts) vivent *moins longtemps* (ou aussi longtemps) que le propriétaire des données.
Vous les voyez surtout dans les signatures de fonctions qui prennent et retournent des références.
Le ProblĂšme (Dangling Reference)
fn main() {
let reference_invalide;
{
let x = 5;
reference_invalide = &x; // Emprunt de 'x'
} // <-- 'x' est "drop" ici
// 'reference_invalide' pointe vers de la mémoire libérée !
println!("{}", reference_invalide);
// ERREUR: "`x` does not live long enough"
}
La Solution (Annotation 'a)
Ex: Une fonction qui retourne la plus longue de deux chaßnes (par référence).
// 'a (lire: "lifetime a")
// "Cette fonction prend deux &str, qui vivent
// au moins 'a', et retourne un &str qui
// vit aussi 'a'."
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
// Le compilateur s'assure que le 'a'
// (la plus petite durée de vie) est respecté.Result)Rust n'a pas d'exceptions (try/catch). Il gÚre les erreurs "récupérables" via l'Enum Result.
// DĂ©finition de l'Enum Resultenum Result { Ok(T), // SuccĂšs, contient la valeur T Err(E), // Ăchec, contient l'erreur E }
1. Gérer avec match
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Result::Ok(fichier) => fichier,
Result::Err(erreur) => {
// (Erreur non récupérable)
panic!("Pb ouverture: {:?}", erreur)
}
};
}
2. Propager avec ?
L'opérateur ? est un raccourci : "Si c'est Ok(T), donne T. Si c'est Err(E), return Err(E) (propage l'erreur)".
use std::fs::File;
use std::io::{self, Read};
// (La fonction doit retourner un Result)
fn lire_fichier() -> Result {
let mut f = File::open("hello.txt")?; // (Propage si erreur)
let mut s = String::new();
f.read_to_string(&mut s)?; // (Propage si erreur)
Ok(s) // (Retourne Ok(string) si succĂšs)
}
// (On peut mĂȘme chaĂźner)
// fn lire_fichier() -> Result {
// fs::read_to_string("hello.txt")?
// }
Un **Trait** est similaire à une interface dans d'autres langages. Il définit un ensemble de méthodes qu'un type doit implémenter pour offrir un comportement spécifique.
// 1. Définir le Trait
pub trait Resume {
fn resumer(&self) -> String;
// (Méthode par défaut)
fn resumer_court(&self) -> String {
format!("(Lire la suite...)")
}
}
// 2. Définir une Struct
pub struct Article {
pub titre: String,
pub contenu: String,
}
// 3. Implémenter le Trait pour la Struct
impl Resume for Article {
fn resumer(&self) -> String {
format!("Titre: {}, Contenu: {}...", self.titre, &self.contenu[..50])
}
}
// 4. Utiliser (via Generics ou 'dyn')
// (Accepte tout type qui implémente 'Resume')
pub fn notifier(item: &T) {
println!("Nouveau résumé ! {}", item.resumer());
}
fn main() {
let article = Article {
titre: String::from("Rust"),
contenu: String::from("Rust est super...")
};
notifier(&article);
} <T>Les "Generics" (Génériques) permettent d'écrire du code (fonctions, structs, enums) qui fonctionne avec plusieurs types (T), sans duplication de code.
(Option et Result sont des enums génériques).
Dans les Structs
// T et U sont des types génériques
struct Point {
x: T,
y: U,
}
fn main() {
// Point
let p_entier = Point { x: 5, y: 10 };
// Point
let p_flottant = Point { x: 1.0, y: 4.0 };
// Point
let p_mixte = Point { x: 5, y: 4.0 };
} Dans les Fonctions
// (Exemple 'longest' vu avant)
fn longest<'a, T>(x: &'a T, y: &'a T) -> &'a T {
// ...
// (Ici on aurait besoin d'un 'Trait bound'
// T: PartialOrd, pour pouvoir comparer)
}
rust-analyzer)L'outillage (tooling) de Rust est considéré comme l'un de ses points forts.
| Outil | Description |
|---|---|
rust-analyzer | Le Language Server (LSP) officiel. C'est le moteur qui fournit l'autocomplétion, la détection d'erreurs en direct, le refactoring, etc. C'est l'outil indispensable. |
| VS Code | Le choix le plus populaire. L'extension "Rust" (officielle) utilise rust-analyzer. |
| JetBrains (CLion / IntelliJ) | Le plugin "Rust" pour IntelliJ ou (mieux) CLion est une alternative trÚs puissante, avec un excellent support du débuggage. |
clippy | Un "linter" (analyseur de style) extrĂȘmement puissant. Il dĂ©tecte les anti-patterns et suggĂšre des amĂ©liorations. (cargo clippy) |
rustfmt | Le formateur de code officiel. (cargo fmt) |
Le Concept : Accélérer Python
Python est facile à écrire, mais lent à l'exécution (ex: calculs intensifs, boucles lourdes).
Rust est rapide, mais plus complexe à écrire.
La solution : Ăcrire le "cĆur" (le "goulot d'Ă©tranglement") en Rust, le compiler en module natif (.so ou .pyd), et l'appeler depuis Python comme une bibliothĂšque classique (import mon_module_rust).
C'est la meilleure combinaison : la vitesse de Rust avec la flexibilité de Python.
PyO3 (Les "Bindings")
PyO3 est un "crate" (librairie) Rust qui gĂšre la "traduction" entre les types Rust (String, i32) et les types Python (str, int).
Il utilise des macros (#[py...]) pour exposer du code Rust Ă Python.
// (Dans src/lib.rs)
use pyo3::prelude::*;
/// Calcule la somme de deux nombres
#[pyfunction]
fn somme_en_rust(a: i64, b: i64) -> PyResult {
Ok(a + b)
}
/// (Définit le module Python)
#[pymodule]
fn mon_module_rust(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(somme_en_rust, m)?)?;
Ok(())
}
Maturin (L'Outil de Build)
Maturin est l'outil (écrit en Python) qui gÚre la compilation du projet Rust et sa transformation en "Python Wheel" (.whl) installable par pip.
Il gĂšre aussi les environnements virtuels (venv).
# (Installer maturin)
pip install maturin
# (Configurer Cargo.toml pour un module Python)
# [lib]
# name = "mon_module_rust"
# crate-type = ["cdylib"]
#
# [dependencies.pyo3]
# version = "0.20.0"
# features = ["extension-module"]
# (Compiler le code Rust en .whl)
maturin build --release
# (Installer la wheel dans l'env python)
pip install target/wheels/mon_module_rust-0.1.0-....whl
# (Utiliser en Python)
# >>> import mon_module_rust
# >>> mon_module_rust.somme_en_rust(5, 10)
# 15Rust excelle lĂ oĂč la performance et la fiabilitĂ© sont critiques.
| Domaine | Description | Exemples (Frameworks / Outils) |
|---|---|---|
| Outils CLI | Rust est parfait pour les outils en ligne de commande (rapide, binaire unique, sûr). | ripgrep (grep), bat (cat), exa (ls) |
| Web (Backend) | Haute performance, faible utilisation mémoire, concurrence (idéal pour les microservices). | Actix Web, Rocket, Axum |
| Web (Frontend) | Compilation en WebAssembly (WASM) pour exécuter du code natif dans le navigateur (ex: jeux, outils graphiques). | Yew, Leptos, (outils: Vite/Rollup plugins) |
| SystÚmes Embarqués | Peut tourner "bare metal" (sans OS), sécurité cruciale pour l'IoT ou l'automobile. | embedded-hal |
| Infrastructure | Bases de données, Outils DevOps, Parties de navigateurs (ex: Firefox), OS. | MeiliSearch (Search engine), Polars (Dataframe) |
Déclarations
// Variable (immuable)
let x: i32 = 5;
// Variable (mutable)
let mut y = 10;
// Constante (type obligatoire)
const MAX: u32 = 100_000;
// Fonction
fn ma_fn(arg: &str) -> bool {
true
}
// Struct (Objet)
struct User {
nom: String,
age: u32,
}
// Enum (Type variant)
enum Statut {
Ok,
EnCours(u32),
Erreur { msg: String },
}Concepts
// Implémentation (Méthodes)
impl User {
// ('static' method)
fn new(nom: String) -> User {
User { nom, age: 0 }
}
// ('instance' method)
fn get_age(&self) -> u32 {
self.age
}
}
// Trait (Interface)
trait Clickable {
fn click(&self);
}
// Pattern Matching
match statut {
Statut::Ok => println!("OK"),
Statut::EnCours(pct) => println!("{}%", pct),
Statut::Erreur { msg } => panic!("{}", msg),
}
// Emprunts
let u = User::new(String::from("A"));
let age_ref = u.get_age(); // Emprunt (&self)
