Condividi tramite


Esercitazione sul lettore RSS (Rust per Windows con VS Code)

L'argomento precedente ha introdotto Rust per Windows e la crate di Windows.

Ora si proverà Rust per Windows scrivendo una semplice app console che scarica i titoli dei post di blog da un feed RSS (Really Simple Syndication).

  1. Avviare un prompt dei comandi (cmd.exe) e cd a una cartella in cui si vogliono mantenere i progetti Rust.

  2. Usando Cargo, creare un nuovo progetto Rust denominato rss_readere cd nella cartella appena creata:

    > cargo new rss_reader
    >     Created binary (application) `rss_reader` package
    > cd rss_reader
    
  3. Aprire quindi il progetto rss_reader in VS Code.

    code .
    
  4. Implementare il progetto rss_reader principale. Aprire prima di tutto il file Cargo.toml nella radice del progetto. Un file Cargo.toml è un file di testo che descrive un progetto Rust, incluse eventuali dipendenze presenti.

    Aggiungere una dipendenza dalla crate di windows, come illustrato nell'elenco seguente. Il crate di Windows è grande. Per mantenere i tempi di compilazione rapidi, si selezioneranno solo le funzionalità Foundation_Collections e Web_Syndication necessarie per questo codice.

    # Cargo.toml
    ...
    
    [dependencies.windows] 
    version = "0.43.0"
    features = [
        "Foundation_Collections",
        "Web_Syndication",
    ]
    
  5. Aprire quindi il file di codice sorgente src/main.rsdel progetto rss_reader . Qui si troverà il codice "Hello, world!" predefinito Cargo. Aggiungere l'istruzione di uso seguente all'inizio di main.rs:

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

    La dichiarazione d’uso abbrevierà il percorso dei tipi che verranno usati. È presente il tipo URI menzionato in precedenza.

  6. Per creare un nuovo URI, sostituire la funzione principale predefinita di Cargo con questo:

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

    Si noti che il tipo restituito della funzione principale è un Risultato, da windows::core::. In questo modo è più semplice gestire gli errori delle API del sistema operativo. windows::core::Result consente la propagazione degli errori e la gestione concisa degli errori.

    È possibile visualizzare l'operatore punto interrogativo alla fine della riga di codice. Per risparmiare sulla digitazione, è possibile usare la logica di propagazione degli errori e corto circuito di Rust. Ciò significa che non è necessario eseguire una serie di operazioni manuali di gestione degli errori per questo semplice esempio. Per altre info su questa funzionalità di Rust, vedi l’operatore ? per semplificare la gestione degli errori.

    Si noti anche il h! macro del crate di Windows. Viene usato per costruire un riferimento HSTRING da un valore letterale stringa Rust. L'API WinRT usa HSTRING per i valori stringa.

  7. Per scaricare il feed RSS, verrà creato un nuovo 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 nuova funzione è un costruttore Rust. Tutti gli oggetti nel crate di windows seguono la convenzione rust e denominano i costruttori nuovo.

  8. È ora possibile usare il SyndicationClient per recuperare il feed.

    // 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(())
    }
    

    Poiché RetrieveFeedAsync è un'API asincrona, viene usata la funzione di blocco ottenere per semplificare l'esempio. In alternativa, è possibile usare l'operatore await all'interno di una funzione async per attendere in modo cooperativo i risultati. Un'app più complessa con un'interfaccia utente grafica userà spesso async.

  9. A questo punto è possibile scorrere gli elementi risultanti e stampare solo i titoli. Di seguito sono riportate anche alcune righe di codice aggiuntive per impostare un'intestazione dell'agente utente, perché alcuni feed RSS richiedono questo tipo di codice.

    // 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. A questo punto è possibile confermare che è possibile compilare ed eseguire facendo clic su Esegui>Esegui senza eseguire il debug (o premendo CTRL+F5). Se vengono visualizzati messaggi imprevisti, assicurarsi di aver completato correttamente l’esercitazione Hello, world! (Rust con VS Code).

    Sono inoltre disponibili Debug e Eseguire i comandi incorporati nell'editor di testo. In alternativa, da un prompt dei comandi nella cartella rss_reader digitarecargo run, che compilerà e quindi eseguirà il programma.

    Comandi Debug ed Esecuzione incorporati nell'editor di testo

    Nel riquadro terminale di VS Code, è possibile notare che Cargo scarica e compila correttamente il crate di Windows, memorizzando nella cache i risultati e usandoli per completare le compilazioni successive in meno tempo. Compila quindi l'esempio e lo esegue, visualizzando un elenco di titoli dei post di blog.

    Elenco dei titoli dei post di blog

È così semplice come programmare Rust per Windows. Dietro le quinte, tuttavia, un sacco di amore va a creare gli strumenti in modo che Rust possa analizzare entrambi i file .winmd basati su ECMA-335 (Common Language Infrastructure, o CLI) e anche fedelmente rispettare fedelmente l'interfaccia binaria dell'applicazione basata su COM (ABI) in fase di esecuzione con sicurezza ed efficienza in mente.

Visualizzazione di una finestra di messaggio

Abbiamo detto che Rust per Windows consente di chiamare qualsiasi API Windows (passato, presente e futuro). In questa sezione verranno quindi visualizzate alcune finestre di messaggio di Windows.

  1. Proprio come per il progetto RSS, al prompt dei comandi cd alla cartella con i progetti Rust.

  2. Creare un nuovo progetto denominato message_boxe aprirlo in VS Code:

    > cargo new message_box
    >     Created binary (application) `message_box` package
    > cd message_box
    > code .
    
  3. In VS Code aprire Cargo.toml e aggiungere le dipendenze di Windows per questo progetto:

     # message_box\Cargo.toml
     ...
    
     [dependencies.windows]
     version = "0.43.0"
     features = [
         "Win32_Foundation",
         "Win32_UI_WindowsAndMessaging",
     ]
    
  4. Aprire ora il file src/main.rs del progetto e aggiungere le dichiarazioni di use con i nuovi spazi dei nomi (come illustrato di seguito). Aggiungere infine il codice per chiamare le funzioni di MessageBoxA e MessageBoxW. La documentazione dell'API Di Windows viene scritta principalmente con C/C++, pertanto è utile confrontare la documentazione dell'API con la documentazione per le proiezioni Rust nel crate di Windows: MessageBoxA (Rust) e 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);
        }
    }
    

    Come si può notare, è necessario usare queste API Win32 in un blocco di unsafe (vedere blocchi unsafe). Si noti anche il s! e w! macro, che creano LPCSTR e argomenti LPCWSTR da valori letterali stringa rust UTF-8; proprio come abbiamo creato un HSTRING con il h! macro per rss_reader. Rust è unicode in modo nativo con stringhe UTF-8, quindi l'uso delle API Windows Wide Unicode (W-suffisso) è preferibile rispetto alle API ANSI (A-suffisso). Questo può essere importante se si usa testo non in inglese nel codice.

Questo può essere importante se si usa testo non in inglese nel codice.