Partilhar via


Tutorial do leitor RSS (Rust para Windows com VS Code)

O tópico anterior introduziu Rust para Windows, e a caixa do Windows.

Agora vamos experimentar o Rust para Windows escrevendo um aplicativo de console simples que baixa os títulos de postagens de blog de um feed RSS (Really Simple Syndication).

  1. Inicie um prompt de comando (cmd.exe) e cd para uma pasta onde você deseja manter seus projetos Rust.

  2. Usando o Cargo, crie um novo projeto Rust chamado rss_reader e cd para a pasta recém-criada:

    > cargo new rss_reader
    >     Created binary (application) `rss_reader` package
    > cd rss_reader
    
  3. Em seguida, abra o projeto rss_reader no VS Code.

    code .
    
  4. Vamos implementar o projeto principal rss_reader. Primeiro, abra o Cargo.toml arquivo na raiz do projeto. Um Cargo.toml arquivo é um arquivo de texto que descreve um projeto Rust, incluindo quaisquer dependências que ele tenha.

    Adicione uma dependência na biblioteca windows , conforme mostrado na listagem abaixo. A caixa de janelas é grande. Para manter os tempos de compilação rápidos, selecionaremos apenas as Foundation_Collections e Web_Syndication funcionalidades necessárias para esse código.

    # Cargo.toml
    ...
    
    [dependencies.windows] 
    version = "0.43.0"
    features = [
        "Foundation_Collections",
        "Web_Syndication",
    ]
    
  5. Em seguida, abra o arquivo de código-fonte do src/main.rs. Lá você encontrará o código padrão "Olá, mundo!" do Cargo. Adicione a seguinte instrução use ao início de main.rs:

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

    Uso da declaração encurta o caminho para os tipos que usaremos. Há o tipo Uri que mencionamos anteriormente.

  6. Para criar um novoUri de , substitua a função principal padrão do Cargo por esta:

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

    Observe que o tipo de retorno da função principal do é um Result, de windows::core::. Isso facilitará as coisas, já que é comum lidar com erros de APIs do sistema operacional (SO). windows::core::Result nos ajuda com a propagação de erros e o tratamento conciso de erros.

    Você pode ver o operador de ponto de interrogação no final da linha de código. Para economizar na digitação, fazemos isso para usar a lógica de propagação de erros e curto-circuito do Rust. Isso significa que não precisamos fazer um monte de tratamento manual de erros para este exemplo simples. Para obter mais informações sobre esse recurso do Rust, consulte O operador ? para facilitar o tratamento de erros.

    Observe também a macro h! do crate windows. Usamos isso para construir uma referência de HSTRING a partir de um literal de string Rust. A API WinRT usa HSTRING extensivamente para valores de cadeia de caracteres.

  7. Para baixar o feed RSS, criaremos um novo SyndicationClient.

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

    A nova função é um construtor Rust. Todos os objetos no crate seguem a convenção Rust e nomeiam os construtores new.

  8. Agora podemos usar o SyndicationClient para recuperar o 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(())
    }
    

    Como RetrieveFeedAsync é uma API assíncrona, usamos a função get de bloqueio para manter o exemplo simples. Alternativamente, poderíamos usar o await operador dentro de uma async função para esperar cooperativamente pelos resultados. Um aplicativo mais complexo com uma interface gráfica do usuário frequentemente usará async.

  9. Agora podemos iterar sobre os itens resultantes, e vamos imprimir apenas os títulos. Você também verá algumas linhas extras de código abaixo para definir um cabeçalho de agente do usuário, já que alguns feeds RSS exigem isso.

    // 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. Agora vamos confirmar que podemos compilar e executar clicando em Executar>Executar sem Depurar (ou pressionando Ctrl+F5). Se vir alguma mensagem inesperada, certifique-se de que concluiu com sucesso o tutorial Olá, mundo! (Rust com VS Code).

    Há também os comandos Debug e Executar incorporados dentro do editor de texto. Como alternativa, na pasta rss_reader, abra um prompt de comando e digite cargo run, que irá construir e, em seguida, executar o programa.

    Os comandos Depurar e Executar incorporados no editor de texto

    No painel VS Code Terminal, você pode ver que o Cargo baixa e compila com êxito as janelas caixa, armazenando em cache os resultados e usando-os para concluir as compilações subsequentes em menos tempo. Em seguida, ele cria o exemplo e o executa, exibindo uma lista de títulos de postagens de blog.

    Lista de títulos de posts de blog

Isso é tão simples quanto programar Rust para Windows. Sob o capô, no entanto, muito amor é dedicado à construção das ferramentas para que Rust possa tanto analisar os .winmd arquivos com base em ECMA-335 (Common Language Infrastructure, ou CLI), e também honrar fielmente a interface binária de aplicativo baseada em COM (ABI) em tempo de execução, focado tanto na segurança quanto na eficiência.

Mostrando uma caixa de mensagem

Nós dissemos que o Rust para Windows permite que você chame qualquer API do Windows (passado, presente e futuro). Então, nesta seção, mostraremos algumas caixas de mensagem do Windows.

  1. Assim como fizemos para o projeto RSS, no prompt de comando, navegue para a pasta com os seus projetos Rust através do comando cd.

  2. Crie um novo projeto chamado message_box e abra-o no VS Code:

    > cargo new message_box
    >     Created binary (application) `message_box` package
    > cd message_box
    > code .
    
  3. No VS Code, abra o Cargo.tomle adicione as dependências do Windows para este projeto:

     # message_box\Cargo.toml
     ...
    
     [dependencies.windows]
     version = "0.43.0"
     features = [
         "Win32_Foundation",
         "Win32_UI_WindowsAndMessaging",
     ]
    
  4. Agora abra o arquivo do src/main.rs projeto e adicione as use declarações com os novos namespaces (como mostrado abaixo). E, finalmente, adicione código para chamar as funções MessageBoxA e MessageBoxW. Os documentos da API do Windows são escritos principalmente com C/C++ em mente, por isso é útil comparar a documentação da API com a documentação das projeções em Rust no crate 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);
        }
    }
    

    Como você pode ver, devemos usar essas APIs do Win32 em um unsafe bloco (consulte Blocos inseguros). Note também os s! e w! macros, que criam LPCSTR e LPCWSTR argumentos a partir de literais de string Rust UTF-8; semelhante a como criámos um HSTRING com o h! macro para rss_reader. Rust é nativamente Unicode com strings UTF-8, portanto, usar as APIs amplas do Windows Unicode (W-suffix) é preferível sobre as APIs ANSI (A-suffix). Isso pode ser importante se você usar texto diferente do inglês em seu código.

Desta vez, quando você cria e executa, o Rust exibe duas caixas de mensagem do Windows.