rust-best-practices

Guide pour écrire du code Rust idiomatique basé sur le manuel des bonnes pratiques d'Apollo GraphQL. Utilisez cette skill quand : (1) vous écrivez du nouveau code ou de nouvelles fonctions Rust, (2) vous révisez ou refactorisez du code Rust existant, (3) vous choisissez entre emprunt, clonage ou patterns de possession, (4) vous implémentez la gestion d'erreurs avec les types `Result`, (5) vous optimisez du code Rust pour les performances, (6) vous écrivez des tests ou de la documentation pour des projets Rust.

npx skills add https://github.com/apollographql/skills --skill rust-best-practices

Bonnes pratiques Rust

Appliquez ces directives lors de l'écriture ou de la révision de code Rust. Basé sur le Rust Best Practices Handbook d'Apollo GraphQL.

Référence des bonnes pratiques

Avant de faire une revue, familiarisez-vous avec les bonnes pratiques Rust d'Apollo. Lisez TOUS les chapitres pertinents en parallèle dans le même tour. Référencez ces fichiers quand vous donnez un retour :

Référence rapide

Borrowing & Ownership

  • Préférez &T à .clone() sauf si un transfert de propriété est requis
  • Utilisez &str plutôt que String, &[T] plutôt que Vec<T> dans les paramètres de fonction
  • Les petits types Copy (≤24 octets) peuvent être passés par valeur
  • Utilisez Cow<'_, T> quand la propriété est ambiguë

Gestion des erreurs

  • Retournez Result<T, E> pour les opérations susceptibles de échouer; évitez panic! en production
  • Ne jamais utiliser unwrap()/expect() en dehors des tests
  • Utilisez thiserror pour les erreurs de bibliothèque, anyhow pour les binaires uniquement
  • Préférez l'opérateur ? aux chaînes de correspondance pour la propagation d'erreurs

Performance

  • Toujours faire un benchmark avec le flag --release
  • Exécutez cargo clippy -- -D clippy::perf pour des conseils de performance
  • Évitez le clonage dans les boucles; utilisez .iter() au lieu de .into_iter() pour les types Copy
  • Préférez les itérateurs aux boucles manuelles; évitez les appels .collect() intermédiaires

Linting

Exécutez régulièrement : cargo clippy --all-targets --all-features --locked -- -D warnings

Lints clés à surveiller :

  • redundant_clone - clonage inutile
  • large_enum_variant - variantes surdimensionnées (considérez l'encadrement)
  • needless_collect - collection prématurée

Utilisez #[expect(clippy::lint)] plutôt que #[allow(...)] avec un commentaire de justification.

Testing

  • Nommez les tests de manière descriptive : process_should_return_error_when_input_empty()
  • Une assertion par test si possible
  • Utilisez les doc tests (///) pour les exemples d'API publique
  • Considérez cargo insta pour les tests de snapshot de sortie générée

Generics & Dispatch

  • Préférez les génériques (dispatch statique) pour le code critique en performance
  • Utilisez dyn Trait seulement quand des collections hétérogènes sont nécessaires
  • Encadrez aux limites de l'API, pas en interne

Type State Pattern

Encodez les états valides dans le système de type pour attraper les opérations invalides à la compilation :

struct Connection<State> { /* ... */ _state: PhantomData<State> }
struct Disconnected;
struct Connected;

impl Connection<Connected> {
    fn send(&self, data: &[u8]) { /* only connected can send */ }
}

Documentation

  • Les commentaires // expliquent pourquoi (sécurité, contournements, rationale de conception)
  • Les commentaires doc /// expliquent quoi et comment pour les APIs publiques
  • Chaque TODO a besoin d'un problème lié : // TODO(#42): ...
  • Activez #![deny(missing_docs)] pour les bibliothèques

Skills similaires