Acheter version papier

Rust

Fork me on GitHub

III. Aller plus loin

4. Documentation et rustdoc

En plus du compilateur, Rust possède un générateur de documentation. Toute la documentation en ligne de la bibliothèque standard (disponible ici) a été générée avec cet outil. Vous allez voir qu'il est très facile de s'en servir.

Génération de la documentation

Avant de voir comment écrire la documentation, je pense qu'il serait plus intéressant de voir comment la générer et surtout à quoi ça ressemble.

Si vous utilisez Cargo, rien de plus simple :

cargo doc

Votre documentation se trouvera dans le dossier target/doc/le_nom_de_votre_cagette/. Pour l'afficher, ouvrez le fichier index.html qui s'y trouve avec votre navigateur internet préféré, ou utilisez la commande :

cargo doc --open

Ce qui devrait vous ouvrir une page dans votre navigateur. Si je lance cargo doc --open sur la crate sysinfo, la page ressemblera à ça :


Page de documentation

Maintenant, si vous souhaitez le faire sans passer par Cargo :

rustdoc le_nom_de_votre_fichier_source

Le contenu sera généré dans le dossier doc/. Pour consulter la documentation générée, c'est pareil que pour Cargo.

Il est important de noter que rustdoc accepte aussi les fichiers markdown (.md) comme argument :

rustdoc fichier.md

Cela créera un fichier doc/fichier.html.

Ajouter de la documentation

Pour le moment, la documentation qu'on a généré ne contient que du code sans rien d'autre. Pas génial pour de la documentation donc... Au final, ce serait bien qu'on ait des explications sur les items, comme ici :


Fonction commentaire

Pour cela, rien de plus simple, il suffit d'utiliser les "///" (aussi appelé "doc comments") :

Run/// Et ici je mets la description
/// que je veux !
fn une_fonction() {}

/// Et le markdown aussi fonctionne :
/// 
/// ```
/// println!("quelque chose");
/// // ou même un exemple d'utilisation de la structure !
/// ```
struct UneStruct {
    /// ce champ sert à faire ceci
    un_champ: 32,
    /// et ce champ sert à faire cela
    un_autre_champ: i32
}

Bon à savoir : /// est du sucre syntaxique qui est remplacé par #[doc = "..."]. Si vous vous souvenez du chapitre sur les attributs, cela signifie que l'on peut avoir l'équivalent interne de cet attribut :

Run//! Je documente l'item dans lequel je suis.
#![doc = "Je suis la deuxième ligne de cette documentation."]
//! Et moi la troisième.

La documentation en Rust utilise le format commonmark, qui est une spécification de markdown. Donc vous pouvez ajouter du style sans problème. Par-exemple :

Run/// _italique_ *italique aussi*
/// _gras_ **gras aussi**
/// `code inline`
/// # Gros titre
/// ## Titre plus petit
/// [lien vers mon site](https://blog.guillaume-gomez.fr)

Je vous invite maintenant à essayer cela sur vos codes pour voir le résultat obtenu. Il est cependant important de noter que les "///" doivent être mis avant l'objet qu'ils doivent documenter. Ce code ne fonctionnera donc pas :

Runenum Option<T> {
    None,
    Some(T), /// Some value `T`
}

Lien intra-doc

Une autre fonctionnalité très utile appelée "lien intra-doc" permet de générer des liens vers des items. Par-exemple :

Run/// Cette fonction retourne un [Type].
pub fn fonction() -> Type {
    Type
}

/// Cette structure est créé dans la fonction [fonction].
pub struct Type;

Dans l'exemple ci-dessus, [Type] et [fonction] seront des liens qui pointeront vers les pages de Type et de fonction. Ils fonctionnent aussi avec les paths :

Run/// Ce type peut être initialisé avec la méthode [Type::new].
pub struct Type;

impl Type {
    pub fn new() -> Type {
        Type
    }
}

[Type::new] pointera vers la méthode new de Type.

Cacher un item

Si vous souhaitez pouvoir utiliser un item défini dans une crate mais que cet item n'apparaisse pas dans la documentation, vous pouvez le cacher avec #[doc(hidden)] :

Run#[doc(hidden)]
pub struct Struct;

Struct ne sera donc pas généré dans la documentation et ne pourra pas être trouvé avec la fonctionnalité de recherche.

Ajouter un alias de recherche

La fonctionnalité de recherche est très pratique dans rustdoc, et il est possible de s'assurer que certaines recherches renvoient des items dont le nom n'a rien à voir en utilisant #[doc(alias)] :

Run#[doc(alias = "error")]
#[doc(alias = "Error")]
pub struct JeSuisUneErreur;

Avec ces 2 alias, que l'on cherche "error" ou "Error", JeSuisUneErreur sera affiché parmi les résultats.

Personnalisation du rendu

Il est possible de personnaliser quelques éléments dans la documentation générée, comme la favicon (l'image miniature dans l'onglet de votre navigateur) ou le logo dans la barre latérale :

Run// Pour changer la favicon.
#![doc(html_favicon_url = "https://example.com/favicon.ico")]
// Pour changer le logo.
#![doc(html_logo_url = "https://example.com/logo.jpg")]

Ces 2 attributs doivent être utilisés dans le module racine du projet, donc très sans doute dans le fichier main.rs ou lib.rs en fonction de si votre crate est un binaire ou une bibliothèque.

Voilà, vous savez maintenant gérer des documentations en Rust ! Il reste toutefois un point que nous n'avons pas abordé : il est possible d'ajouter des exemples de codes qui seront testés directement dans votre documentation. Nous allons en parler dans le prochain chapitre.