Partager via


Tutoriel sur le lecteur RSS (Rust pour Windows avec VS Code)

La rubrique précédente a introduit Rust pour Windows et le crate windows.

Nous allons maintenant essayer Rust pour Windows en écrivant une application console simple qui télécharge les titres des billets de blog à partir d’un flux RSS (Really Simple Syndication).

  1. Lancez une invite de commandes (cmd.exe) et cd dans un dossier dans lequel vous souhaitez conserver vos projets Rust.

  2. À l’aide de Cargo, créez un projet Rust nommé rss_readeret cd dans le dossier nouvellement créé :

    > cargo new rss_reader
    >     Created binary (application) `rss_reader` package
    > cd rss_reader
    
  3. Ouvrez ensuite le projet rss_reader dans VS Code.

    code .
    
  4. Implémentons le projet principal du lecteur RSS . Tout d’abord, ouvrez le fichier Cargo.toml à la racine du projet. Un fichier Cargo.toml est un fichier texte qui décrit un projet Rust, y compris les dépendances qu’il possède.

    Ajoutez une dépendance sur le crate windows , comme indiqué dans l'extrait ci-dessous. Les fenêtres crate sont volumineuses. Pour accélérer la génération, nous allons sélectionner uniquement les fonctionnalités Foundation_Collections et Web_Syndication dont nous avons besoin pour ce code.

    # Cargo.toml
    ...
    
    [dependencies.windows] 
    version = "0.43.0"
    features = [
        "Foundation_Collections",
        "Web_Syndication",
    ]
    
  5. Ensuite, ouvrez le fichier de code source du projet src/main.rs. Vous trouverez le code Cargo par défaut « Hello, world ! ». Ajoutez l'instruction suivante au début de main.rs:

    // src\main.rs
    use windows::{
        core::*,
        Foundation::Uri,
        Web::Syndication::SyndicationClient
    };
    
    fn main() {
        println!("Hello, world!");
    }
    

    La déclaration utiliser raccourcit le chemin d’accès aux types que nous utiliserons. Il existe le type Uri que nous avons mentionné précédemment.

  6. Pour créer un Uri, remplacez la fonction principale par défaut de Cargo par celle-ci :

    // src\main.rs
    ...
    
    fn main() -> Result<()> {
        let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?;
    
        Ok(())
    }
    

    Notez que le type de retour de la fonction principale est unde résultat , à partir de windows ::core ::. Cela facilite les choses, car il est courant de traiter les erreurs des API du système d’exploitation. windows ::core ::Result nous aide à la propagation des erreurs et à la gestion concise des erreurs.

    Vous pouvez voir l’opérateur de point d’interrogation à la fin de la ligne de code. Pour économiser la saisie, nous faisons cela pour utiliser la logique de propagation des erreurs et de court-circuitage de Rust. Cela signifie que nous n’avons pas besoin d’effectuer un ensemble de gestion manuelle des erreurs pour cet exemple simple. Pour plus d'informations sur cette fonctionnalité de Rust, consultez l'opérateur ? pour faciliter la gestion des erreurs.

    Notez également la macro h ! du module fenêtres. Nous l’utilisons pour construire une référence HSTRING à partir d’un littéral de chaîne Rust. L'API WinRT utilise HSTRING pour les valeurs de chaîne.

  7. Pour télécharger le flux RSS, nous allons créer une nouvelle SyndicationClient.

    // src\main.rs
    ...
    
    fn main() -> windows::core::Result<()> {
        let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?;
        let client = SyndicationClient::new()?;
    
        Ok(())
    }
    

    La nouvelle fonction est un constructeur Rust. Tous les objets de la caisse windows suivent la convention Rust et nomment leurs constructeurs new.

  8. Maintenant, nous pouvons utiliser le SyndicationClient pour récupérer le flux.

    // src\main.rs
    ...
    
    fn main() -> windows::core::Result<()> {
        let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?;
        let client = SyndicationClient::new()?;
        let feed = client.RetrieveFeedAsync(&uri)?.get()?;
    
        Ok(())
    }
    

    Étant donné que RetrieveFeedAsync est une API asynchrone, nous utilisons la fonction bloquante get pour garder l’exemple simple. Nous pourrions également utiliser l’opérateur await au sein d’une fonction async pour attendre de manière coopérative les résultats. Une application plus complexe avec une interface utilisateur graphique utilise fréquemment async.

  9. Maintenant, nous pouvons itérer sur les éléments résultants, et nous allons imprimer uniquement les titres. Vous verrez également quelques lignes de code supplémentaires ci-dessous pour définir un en-tête de l’agent utilisateur, car certains flux RSS nécessitent cela.

    // src\main.rs
    ...
    
    fn main() -> windows::core::Result<()> {
        let uri = Uri::CreateUri(h!("https://blogs.windows.com/feed"))?;
        let client = SyndicationClient::new()?;
    
        client.SetRequestHeader(
            h!("User-Agent"),
            h!("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"),
        )?;
    
        let feed = client.RetrieveFeedAsync(&uri)?.get()?;
    
        for item in feed.Items()? {
            println!("{}", item.Title()?.Text()?);
        }
    
        Ok(())
    }
    
  10. Nous allons maintenant confirmer que nous pouvons générer et exécuter en cliquant sur Exécuter>Exécuter sans débogage (ou en appuyant sur Ctrl+F5). Si vous voyez des messages inattendus, vérifiez que vous avez correctement terminé la Hello, world ! tutoriel (Rust avec VS Code).

    Il existe également les commandes Debug et Run intégrées dans l’éditeur de texte. Autrement, depuis l'invite de commandes dans le dossier rss_reader, tapez cargo run, ce qui générera puis exécutera le programme.

    Commandes de débogage et d’exécution incorporées dans l’éditeur de texte

    Dans le volet Terminal de VS Code, vous pouvez voir que Cargo télécharge et compile avec succès la crate windows , met en cache les résultats et les utilise pour que les builds suivantes se terminent plus rapidement. Il génère ensuite l’exemple et l’exécute, affichant une liste de titres de billet de blog.

    Liste des titres de billet de blog

C’est aussi simple que de programmer Rust pour Windows. Toutefois, sous le capot, beaucoup d’amour est consacré à la création des outils pour que Rust puisse à la fois analyser les fichiers .winmd basés sur ECMA-335 (Common Language Infrastructure ou CLI) et honorer fidèlement l’interface binaire d’application basée sur COM lors de l’exécution, en gardant à l’esprit à la fois la sécurité et l’efficacité.

Affichage d’une boîte de message

Nous avons dit que Rust pour Windows vous permet d’appeler n’importe quelle API Windows (passé, présent et futur). Dans cette section, nous allons afficher quelques boîtes de message Windows.

  1. Comme nous l'avons fait pour le projet RSS, utilisez la commande cd cd pour accéder au dossier contenant vos projets Rust.

  2. Créez un projet nommé message_box, puis ouvrez-le dans VS Code :

    > cargo new message_box
    >     Created binary (application) `message_box` package
    > cd message_box
    > code .
    
  3. Dans VS Code, ouvrez le Cargo.tomlet ajoutez les dépendances Windows pour ce projet :

     # message_box\Cargo.toml
     ...
    
     [dependencies.windows]
     version = "0.43.0"
     features = [
         "Win32_Foundation",
         "Win32_UI_WindowsAndMessaging",
     ]
    
  4. Ouvrez maintenant le fichier src/main.rs du projet et ajoutez les déclarations de use avec les nouveaux espaces de noms (comme indiqué ci-dessous). Enfin, ajoutez du code pour appeler les fonctions MessageBoxA et MessageBoxW. Les documents d’API Windows sont principalement écrits en pensant à C/C++, il est donc utile de comparer les documents d’API aux documents des projections Rust dans le crate windows : MessageBoxA (Rust) et MessageBoxW (Rust).

    // src\main.rs
    use windows::{
        core::*,
        Win32::UI::WindowsAndMessaging::*
    };
    
    fn main() {
        unsafe {
            MessageBoxA(None, s!("Ansi"), s!("World"), MB_OK);
            MessageBoxW(None, w!("Wide"), w!("World"), MB_OK);
        }
    }
    

    Comme vous pouvez le voir, nous devons utiliser ces API Win32 dans un bloc unsafe (voir blocs non sécurisés). Notez également les macros s! et w!, qui créent des arguments LPCSTR et LPCWSTR à partir de littéraux de chaîne UTF-8 Rust ; tout comme nous avons créé un HSTRING avec la macro h! pour rss_reader. Rust est nativement Unicode avec des chaînes UTF-8, il est donc préférable d'utiliser les API Windows Unicode étendu (suffixe W) plutôt que les API ANSI (suffixe A). Cela peut être important si vous utilisez du texte non anglais dans votre code.

Cette fois que vous générez et exécutez, Rust affiche deux boîtes de message Windows.