Files
khadhroony-solana-project/docs/rules/RULES_RUST.md

102 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: docs/rules/RULES_RUST.md -->
<!-- version: 5 -->
# Règles Rust générales
## Portée
Les règles `RUST-*` s'appliquent aux crates, sources, tests, exemples et outils Rust de KSP. Elles sont conçues pour rester réutilisables hors de KSP lorsque la règle ne dépend pas de son architecture.
## Édition et lints
- **RUST-BASE-001** — L'édition Rust est Rust 2024, sauf contrainte externe explicitement documentée.
- **RUST-BASE-002** — Chaque `lib.rs` et `main.rs` contient `#![warn(missing_docs)]`, `#![deny(unreachable_pub)]` et `#![forbid(unsafe_code)]`.
- **RUST-BASE-003** — Les lints communs sont déclarés au niveau workspace et hérités par les crates.
- **RUST-BASE-004** — Le code `unsafe` est interdit.
## Documentation des API
- **RUST-DOC-001** — Tout élément `pub` ou `pub(crate)` possède une rustdoc utile au point de déclaration.
- **RUST-DOC-002** — Toute réexportation `pub use` ou `pub(crate) use` dans `lib.rs` ou `main.rs` possède également une rustdoc utile.
- **RUST-DOC-003** — La façade d'une crate doit permettre de comprendre son API sans dépendre de ses chemins de modules internes.
## Imports et chemins
- **RUST-IMPORT-001** — `use` est interdit pour les constantes, fonctions, structures, énumérations, unions, alias de types, modules et macros.
- **RUST-IMPORT-002** — `use` est autorisé uniquement pour un trait lorsque la résolution de méthode, une macro de dérivation ou une contrainte du langage l'exige réellement.
- **RUST-IMPORT-003** — Un import de trait reste étroit et ne mélange pas de non-traits dans un import groupé.
- **RUST-IMPORT-004** — Les glob imports et imports groupés par accolades sont interdits.
- **RUST-IMPORT-005** — Pour un élément externe, utiliser directement le chemin public le plus court fourni par la crate propriétaire.
- **RUST-IMPORT-006** — Pour un élément `pub` d'une crate KSP, l'API est réexportée au crate-root et consommée depuis une autre crate via `owner_crate::Item`.
- **RUST-IMPORT-007** — Dans sa propre crate, un élément `pub` ou `pub(crate)` partagé est consommé via `crate::Item` après réexport approprié.
- **RUST-IMPORT-008** — Un helper strictement privé au module reste privé et est appelé localement ; dans un sous-module de tests, un élément privé du module parent est appelé via `super::Item`.
- **RUST-IMPORT-009** — Les réexports ne sont pas groupés par accolades et les alias `as` sont interdits dans les réexports.
- **RUST-IMPORT-010** — Un réexport d'un module interne commence par `self::`.
## Visibilité et façade de crate
- **RUST-API-001** — Aucun `pub mod` n'est autorisé ; les modules restent privés et l'API externe est constituée par des réexports explicites au crate-root.
- **RUST-API-002** — `pub(in ...)` et `pub(super)` sont interdits.
- **RUST-API-003** — Un élément `pub` inaccessible depuis la façade de sa crate est une erreur de conception.
- **RUST-API-004** — Un élément `pub(crate)` utilisé hors de son module est réexporté au crate-root via `pub(crate) use`.
- **RUST-API-005** — Les chemins internes de modules ne constituent pas une API stable.
## Contrôle de flux et erreurs
- **RUST-ERR-001** — `unwrap`, `expect` et `panic` sont interdits dans le code de production.
- **RUST-ERR-002** — L'opérateur `?` est interdit dans le code de production ; les chemins d'erreur utilisent un contrôle de flux explicite.
- **RUST-ERR-003** — Les retours sont explicites conformément au lint `clippy::implicit_return`.
- **RUST-ERR-004** — `anyhow` et `thiserror` ne sont pas utilisés par défaut ; leur introduction exige une justification architecturale.
- **RUST-ERR-005** — Les erreurs publiques sont typées lorsque leur contrat est stable.
- **RUST-ERR-006** — Les tests peuvent utiliser `unwrap` ou `expect` uniquement dans la limite explicitement autorisée par la configuration Clippy.
- **RUST-ERR-007** — Avant dattacher une erreur externe comme `source` de `ksp_core_lib::Error`, la crate propriétaire vérifie que sa chaîne `Debug`/`source` ne peut pas exposer de secret ou de donnée sensible. Lorsquune dépendance fournit une primitive de neutralisation, elle est appliquée avant `with_source`; en particulier une `reqwest::Error` issue dune requête vers un endpoint potentiellement credential-bearing est attachée uniquement après `without_url()`.
## Formatage
- **RUST-FMT-001** — `rustfmt.toml` à la racine est la configuration canonique du formatage Rust.
- **RUST-FMT-002** — `cargo fmt --all` est exécuté après chaque modification Rust avant les validations de compilation et de test.
- **RUST-FMT-003** — Les fichiers Rust ne contiennent pas de lignes vides à l'intérieur d'une fonction, structure, énumération ou implémentation courte.
- **RUST-FMT-004** — Les lignes vides séparent uniquement des fonctions, types, blocs `impl` ou sections logiques distinctes.
- **RUST-FMT-005** — Les groupes homogènes de `pub use` ou `pub(crate) use` ne contiennent pas de ligne vide interne ; `pub use` précède `pub(crate) use` lorsqu'ils coexistent.
## Helpers et duplication
- **RUST-HELP-001** — Un helper répété dans plusieurs modules d'une même crate est déplacé dans un module commun dont le nom décrit la responsabilité la plus précise possible.
- **RUST-HELP-002** — Un helper réellement général et réutilisable par plusieurs crates est déplacé dans la bibliothèque KSP appropriée.
- **RUST-HELP-003** — La mutualisation ne doit pas créer de dépendance cyclique ni déplacer une logique métier spécifique dans une bibliothèque générique.
## Dépendances
- **RUST-DEP-001** — Une dépendance n'est ajoutée que si elle est réellement utilisée dans le chemin de compilation concerné.
- **RUST-DEP-002** — Une dépendance uniquement utilisée par les tests reste dans `[dev-dependencies]`.
- **RUST-DEP-003** — Les features sont minimales et explicites.
- **RUST-DEP-004** — Les lockfiles de dépendances ne sont pas versionnés dans KSP.
- **RUST-DEP-005** — KSP privilégie les versions récentes compatibles. Toute version volontairement contrainte ou ancienne doit être documentée avec sa raison et la condition permettant de lever la contrainte.
## Assertions de collections
- **RUST-TEST-001** — Un test vérifiant uniquement l'appartenance à un ensemble peut trier les valeurs obtenues et attendues avant `assert_eq!` lorsque l'ordre n'est pas contractuel.
- **RUST-TEST-002** — Une collection n'est jamais triée artificiellement dans un test lorsque l'ordre fait partie du contrat, notamment pour comptes Solana, metas, instructions, signers, événements, étapes de pipeline, priorités ou journaux ordonnés.
## Organisation des tests
- **RUST-TEST-003** — Les sources de tests unitaires sont placées autant que possible dans un répertoire `unit_tests/` à la racine de la crate et reflètent autant que possible l'arborescence et les noms des modules sous `src/`.
- **RUST-TEST-004** — Un fichier sous `unit_tests/` reste un vrai test unitaire : il est rattaché explicitement sous `#[cfg(test)]` au module de production qu'il teste et peut donc tester ses éléments privés.
- **RUST-TEST-005** — Le répertoire Cargo standard `tests/` est réservé aux tests d'intégration. Les fichiers qui y sont découverts comme cibles d'intégration testent la crate comme un consommateur externe et n'utilisent que son API publique.
- **RUST-TEST-006** — Toute partie pertinente de l'API publique d'une bibliothèque KSP doit, lorsque cela est techniquement possible, être couverte par de vrais tests d'intégration sous `tests/`, afin de valider notamment les réexports, la visibilité et le contrat réellement consommable depuis une autre crate.
- **RUST-TEST-007** — La séparation physique sous `unit_tests/` est la convention préférée et doit être utilisée au maximum. La colocalisation d'un test unitaire dans le fichier/module de production n'est autorisée qu'en dernier recours lorsqu'un rattachement externe serait techniquement impossible, incorrect ou créerait une complexité disproportionnée clairement justifiable.
- **RUST-TEST-008** — Un test unitaire séparé suit autant que possible le même chemin relatif et le même nom que le module testé, afin que la correspondance `src/...``unit_tests/...` soit immédiatement identifiable.
## Contrôle de clôture Rust
Lorsqu'une tranche contient du Rust, les contrôles minimaux sont :
```bash
cargo fmt --all
cargo check --workspace
cargo test --workspace
cargo clippy --workspace --all-targets
```
Les audits structurels automatisés seront ajoutés lorsqu'ils existeront dans KSP ; une règle ne doit pas prétendre qu'un script inexistant a été exécuté.