8.6 KiB
8.6 KiB
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.rsetmain.rscontient#![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
unsafeest interdit.
Documentation des API
- RUST-DOC-001 — Tout élément
puboupub(crate)possède une rustdoc utile au point de déclaration. - RUST-DOC-002 — Toute réexportation
pub useoupub(crate) usedanslib.rsoumain.rspossè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 —
useest interdit pour les constantes, fonctions, structures, énumérations, unions, alias de types, modules et macros. - RUST-IMPORT-002 —
useest 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
pubd'une crate KSP, l'API est réexportée au crate-root et consommée depuis une autre crate viaowner_crate::Item. - RUST-IMPORT-007 — Dans sa propre crate, un élément
puboupub(crate)partagé est consommé viacrate::Itemaprè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
assont 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 modn'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 ...)etpub(super)sont interdits. - RUST-API-003 — Un élément
pubinaccessible 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 viapub(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,expectetpanicsont 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 —
anyhowetthiserrorne 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
unwrapouexpectuniquement dans la limite explicitement autorisée par la configuration Clippy. - RUST-ERR-007 — Avant d’attacher une erreur externe comme
sourcedeksp_core_lib::Error, la crate propriétaire vérifie que sa chaîneDebug/sourcene peut pas exposer de secret ou de donnée sensible. Lorsqu’une dépendance fournit une primitive de neutralisation, elle est appliquée avantwith_source; en particulier unereqwest::Errorissue d’une requête vers un endpoint potentiellement credential-bearing est attachée uniquement aprèswithout_url().
Formatage
- RUST-FMT-001 —
rustfmt.tomlà la racine est la configuration canonique du formatage Rust. - RUST-FMT-002 —
cargo fmt --allest 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
implou sections logiques distinctes. - RUST-FMT-005 — Les groupes homogènes de
pub useoupub(crate) usene contiennent pas de ligne vide interne ;pub useprécèdepub(crate) uselorsqu'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 soussrc/. - 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 :
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é.