0.0.5-alpha.7
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/510-RUST_CARGO.md -->
|
||||
<!-- version: 4 -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Profil Rust / Cargo
|
||||
|
||||
@@ -11,9 +11,13 @@ Il spécialise [`500-LANGUAGES.md`](500-LANGUAGES.md) pour les responsabilités
|
||||
|
||||
Une règle plus spécifique, par exemple Android, WASM, Tauri ou une frontière FFI, MAY raffiner ce profil dans son scope sans modifier la politique Rust générale.
|
||||
|
||||
Pour un **nouveau projet contrôlé** par l'organisation, PGR sélectionne par défaut le profil strict décrit ci-dessous : provenance des symboles visible, façade crate-root explicite, contrôle de flux explicite et noms de crates lisibles. Un projet existant ou imposé par un tiers MAY conserver des contraintes différentes via des règles project-specific ou des exceptions bornées ; cette adaptation ne rend pas le profil strict moins canonique pour les nouvelles baselines contrôlées.
|
||||
|
||||
## Toolchain et édition
|
||||
|
||||
Un nouveau projet Rust SHOULD utiliser une toolchain stable récente compatible avec ses dépendances et ses cibles. Une toolchain nightly, beta ou autre prerelease nécessite une justification explicite.
|
||||
Un nouveau projet Rust contrôlé MUST utiliser l'édition Rust 2024 avec une toolchain stable compatible avec ses dépendances et ses cibles, sauf contrainte externe explicitement documentée. Une toolchain nightly, beta ou autre prerelease nécessite une justification explicite.
|
||||
|
||||
`2024` est la baseline normative actuelle des projets contrôlés ; PGR ne bascule pas automatiquement vers une future édition au seul motif qu'elle existe. Une évolution de cette baseline demande une décision PGR explicite et une validation de compatibilité.
|
||||
|
||||
PGR MUST NOT imposer un pin exact de toolchain uniquement parce qu'un projet source historique utilisait cette version. Un fichier `rust-toolchain.toml` ou équivalent SHOULD être ajouté uniquement lorsqu'un besoin réel de reproductibilité, de composant ou de compatibilité l'exige.
|
||||
|
||||
@@ -34,6 +38,36 @@ Un monorepo contenant plusieurs unités de release indépendantes MUST NOT fabri
|
||||
|
||||
Le répertoire `crates/` est le placement PGR recommandé pour les packages Rust d'un workspace structuré, sauf layout imposé par un framework, une plateforme ou un projet existant.
|
||||
|
||||
|
||||
### Nomenclature des crates dans un projet contrôlé
|
||||
|
||||
Une crate appartenant à un projet contrôlé MUST commencer par le nom court canonique du projet ou une abréviation documentée et stable. Le reste du nom SHOULD rendre immédiatement lisibles sa responsabilité principale puis, lorsqu'il apporte une information réelle, son rôle ou sa cible.
|
||||
|
||||
La forme recommandée est :
|
||||
|
||||
```text
|
||||
<project>-<responsibility>-<role-or-target>
|
||||
```
|
||||
|
||||
Exemples de classificateurs utiles selon le projet :
|
||||
|
||||
```text
|
||||
lib
|
||||
api
|
||||
worker
|
||||
job
|
||||
cli
|
||||
desk
|
||||
desktop
|
||||
tauri
|
||||
wasm
|
||||
server
|
||||
```
|
||||
|
||||
Cette liste n'est ni exhaustive ni un vocabulaire imposé. Un suffixe ou classificateur ne doit pas être ajouté par symétrie : `api` suppose un vrai contrat/extensibility boundary, `worker` un service continu identifiable, `cli` une interface ligne de commande, etc. À l'inverse, un rôle important ne doit pas être masqué dans un nom générique comme `common`, `core` ou `utils` sans responsabilité suffisamment précise.
|
||||
|
||||
Un projet historique MAY conserver un ordre local déjà stable, par exemple un rôle placé avant la responsabilité, si sa nomenclature est documentée et cohérente. PGR n'impose aucune campagne de renommage rétroactive uniquement pour adopter la grammaire recommandée.
|
||||
|
||||
## Manifests et dépendances Cargo
|
||||
|
||||
Dans un workspace, une dépendance tierce réellement partagée par plusieurs crates SHOULD posséder sa contrainte de version canonique sous `[workspace.dependencies]`.
|
||||
@@ -84,28 +118,57 @@ Lorsqu'une FFI ou une plateforme impose réellement une opération `unsafe`, l'e
|
||||
|
||||
Une exception FFI locale n'autorise donc pas à remplacer globalement `unsafe_code = "forbid"` par une politique permissive pour toutes les crates.
|
||||
|
||||
## API, visibilité et rustdoc
|
||||
## API, visibilité, imports et chemins
|
||||
|
||||
Tout élément `pub` ou `pub(crate)` SHOULD posséder une rustdoc utile au point de déclaration lorsque son contrat dépasse une implémentation triviale locale.
|
||||
Dans le profil strict d'un projet contrôlé, tout élément `pub` ou `pub(crate)` MUST posséder une rustdoc utile au point de déclaration. Toute réexportation `pub use` ou `pub(crate) use` visible au crate-root MUST également porter une rustdoc adjacente utile. Une rustdoc qui répète seulement le nom du symbole ne satisfait pas ce contrat.
|
||||
|
||||
Une crate réutilisable SHOULD exposer son API durable depuis son crate-root par des réexports explicites. Les modules d'implémentation SHOULD rester privés ; `pub mod` ne doit pas être utilisé uniquement pour éviter de concevoir une façade stable.
|
||||
Les modules d'implémentation restent privés. `pub mod` MUST NOT être utilisé pour exposer paresseusement une arborescence interne ; `pub(super)` et `pub(in ...)` MUST NOT remplacer une façade crate-root explicite dans une baseline contrôlée.
|
||||
|
||||
Lorsqu'un projet adopte le **contrat strict de façade crate-root**, un élément `pub` d'un module fichier MUST être réexporté explicitement au crate-root. Un élément `pub(crate)` consommé hors de son module MUST de même posséder un réexport `pub(crate)` au crate-root. Un helper réellement local SHOULD rester privé plutôt qu'élargir artificiellement sa visibilité.
|
||||
Un élément `pub` d'un module fichier MUST être réexporté explicitement au crate-root. Un élément `pub(crate)` consommé hors de son module MUST de même posséder un réexport `pub(crate)` au crate-root. Un helper réellement local SHOULD rester privé plutôt qu'élargir artificiellement sa visibilité.
|
||||
|
||||
Dès qu'un item possède cette identité crate-root, toute référence dans la même crate MUST utiliser `crate::Item`, y compris depuis son module de déclaration et depuis ses tests unitaires attachés. Les formes `Item`, `self::Item`, `super::Item`, `module::Item` et `crate::module::Item` ne sont pas des chemins de consommation canoniques pour cet item partagé. Un élément strictement privé reste local au module ; un test unitaire attaché peut alors utiliser `super::PrivateItem`.
|
||||
Les réexports d'éléments internes commencent par `self::` :
|
||||
|
||||
Les autres crates consomment l'API publique du crate propriétaire via `owner_crate::Item` plutôt que ses chemins internes. Les glob imports SHOULD être évités. Un alias de réexport ne doit pas servir à masquer durablement une collision de noms dans l'API ; lorsqu'un nom fait partie du contrat public, le propriétaire SHOULD choisir un nom canonique non ambigu.
|
||||
```rust
|
||||
pub use self::foo::Foo;
|
||||
pub(crate) use self::bar::InternalBar;
|
||||
```
|
||||
|
||||
PGR ne généralise pas l'interdiction KSP plus stricte de tous les `use` non-traits : cette convention appartient à un profil ou projet plus spécifique tant qu'elle n'est pas nécessaire au contrat Rust général.
|
||||
Un réexport de crate externe utilise son chemin public canonique. Les réexports groupés par accolades, les glob imports et les alias `as` servant à raccourcir ou masquer un nom MUST NOT être utilisés. Une collision durable se résout en donnant au symbole son nom canonique dans son module propriétaire.
|
||||
|
||||
### `use` réservé aux traits
|
||||
|
||||
Dans le profil strict, `use` MUST NOT importer une constante, fonction, structure, énumération, union, alias de type, module ou macro uniquement pour raccourcir son chemin. Les déclarations `use` sont réservées aux traits lorsqu'une résolution de méthode ou une contrainte du langage exige réellement leur mise en scope.
|
||||
|
||||
Un import de trait reste au niveau du module et ne mélange pas de symboles non-traits. Un projet MAY ajouter un marqueur de commentaire spécifique à son audit local, mais PGR n'impose pas un commentaire tel que `rust-rules: trait-import` : ce marqueur est un mécanisme d'enforcement, pas la règle sémantique elle-même.
|
||||
|
||||
Pour un élément fourni par une crate externe, le code utilise directement le **chemin public le plus court** exposé par cette crate, par exemple :
|
||||
|
||||
```rust
|
||||
std::path::Path
|
||||
serde_json::Value
|
||||
other_crate::Item
|
||||
```
|
||||
|
||||
et non un `use` non-trait destiné à raccourcir ce chemin. Un chemin interne plus long n'est pas préféré lorsque la crate externe expose déjà une façade publique plus courte.
|
||||
|
||||
### Façade crate-root et références intra-crate
|
||||
|
||||
Dès qu'un item partagé possède une identité crate-root, toute référence dans la même crate MUST utiliser `crate::Item`, y compris depuis son module de déclaration et depuis ses tests unitaires attachés. Les formes `Item`, `self::Item`, `super::Item`, `module::Item` et `crate::module::Item` ne sont pas des chemins de consommation canoniques pour cet item partagé.
|
||||
|
||||
Un élément strictement privé reste local au module et n'est pas réexporté. Dans un fichier de tests unitaires rattaché au module parent, un élément privé du parent peut être référencé via `super::PrivateItem`; un élément `pub` ou `pub(crate)` partagé continue d'être référencé via `crate::Item`.
|
||||
|
||||
Les autres crates consomment l'API publique du crate propriétaire via `owner_crate::Item`, jamais via ses modules internes. La visibilité d'un item MUST NOT être élargie uniquement pour permettre son test.
|
||||
|
||||
Ces conventions sont plus strictes que le Rust idiomatique minimal, mais elles sont retenues pour les projets contrôlés afin de rendre immédiatement visibles l'ownership et la provenance des symboles. Un projet externe contraint peut définir un override explicite ; l'exception ne devient pas la nouvelle règle PGR.
|
||||
|
||||
## Contrôle de flux et erreurs
|
||||
|
||||
Dans le code de production du profil strict PGR :
|
||||
|
||||
- `unwrap()` et `expect()` MUST NOT servir à traiter un chemin d'erreur récupérable ;
|
||||
- `unwrap()` et `expect()` MUST NOT être utilisés ;
|
||||
- `panic!` MUST NOT représenter une erreur métier récupérable ;
|
||||
- les retours explicites sont la convention par défaut ;
|
||||
- l'opérateur `?` est désactivé par le profil Clippy strict afin de conserver des chemins d'erreur explicites.
|
||||
- les retours explicites sont obligatoires lorsque la fonction possède une valeur de retour ;
|
||||
- l'opérateur `?` MUST NOT être utilisé ; les chemins `Ok`/`Err` et conversions d'erreur restent explicites.
|
||||
|
||||
Une règle plus spécifique MAY définir une politique d'erreur différente lorsqu'elle possède une justification architecturale explicite. PGR ne généralise pas l'interdiction d'une bibliothèque d'erreur particulière à partir d'un seul projet source.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user