Compartir a través de


Tutorial del lector RSS (Rust para Windows con VS Code)

El tema anterior introdujo Rust para Windows y el contenedor de ventanas.

Ahora vamos a probar Rust para Windows escribiendo una aplicación de consola sencilla que descarga los títulos de las publicaciones de blog de un canal de sindicación realmente simple (RSS).

  1. Inicie un símbolo del sistema (cmd.exe) y cd en una carpeta donde quiera conservar los proyectos de Rust.

  2. Usando Cargo, crear un nuevo proyecto de Rust llamado rss_reader, y cd a la carpeta recién creada:

    > cargo new rss_reader
    >     Created binary (application) `rss_reader` package
    > cd rss_reader
    
  3. A continuación, abra el proyecto de rss_reader en VS Code.

    code .
    
  4. Vamos a implementar el proyecto principal de rss_reader. En primer lugar, abra el Cargo.toml archivo en la raíz del proyecto. Un Cargo.toml archivo es un archivo de texto que describe un proyecto de Rust, incluidas las dependencias que tiene.

    Agregue una dependencia al crate de Windows , como se muestra en el listado a continuación. La caja de ventanas es grande. Para mantener los tiempos de compilación rápidos, seleccionaremos solo las Foundation_Collections características y Web_Syndication que necesitamos para este código.

    # Cargo.toml
    ...
    
    [dependencies.windows] 
    version = "0.43.0"
    features = [
        "Foundation_Collections",
        "Web_Syndication",
    ]
    
  5. A continuación, abra el archivo de código fuente del proyecto rss_readersrc/main.rs. Allí encontrará el código predeterminado "Hello, world!" de Cargo. Agregue el siguiente use instrucción al principio de main.rs:

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

    El usar declaración acorta la ruta de acceso a los tipos que usaremos. Hay el tipo de Uri que mencionamos anteriormente.

  6. Para crear una nueva Uri, reemplace la función principal de principal de Cargo por esta:

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

    Nota que el tipo de valor devuelto de la función principal de es unResultado de , de windows::core::. Esto hará que las cosas sean más fáciles, ya que es habitual tratar los errores de las API del sistema operativo (SO). windows::core::Result nos ayuda con la propagación de errores y la gestión concisa de estos.

    Puede ver el operador de signo de interrogación al final de la línea de código. Para ahorrar en tecleo, lo hacemos para utilizar la lógica de propagación de errores y cortocircuitaje de Rust. Esto significa que no es necesario realizar un montón de control manual de errores para este ejemplo sencillo. Para obtener más información sobre esta característica de Rust, consulta el operador "?" para facilitar la gestión de errores.

    ¡Observe también el h! macro de las ventanas crate. Usamos eso para construir una referencia de HSTRING a partir de un literal de cadena de Rust. La API de WinRT utiliza extensamente HSTRING para los valores de cadena.

  7. Para descargar la fuente RSS, crearemos un nuevo 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 nueva función es un constructor de Rust. Todos los objetos en el contenedor de ventanas siguen la convención de Rust y nombran a sus constructores nuevo.

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

    Dado que RetrieveFeedAsync es una API asincrónica, usamos la función get de bloqueo para simplificar el ejemplo. Como alternativa, podríamos usar el await operador dentro de una async función para esperar de forma cooperativa los resultados. Una aplicación más compleja con una interfaz gráfica de usuario usará asynccon frecuencia .

  9. Ahora podemos iterar sobre los elementos resultantes y vamos a imprimir solo los títulos. También verá algunas líneas de código adicionales a continuación para establecer un encabezado de agente de usuario, ya que algunas fuentes RSS requieren eso.

    // 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. Ahora vamos a confirmar que podemos compilar y ejecutar haciendo clic en Ejecutar>Ejecutar sin depurar (o presionando Ctrl+F5). Si ve algún mensaje inesperado, asegúrese de que ha completado correctamente el tutorial 'Hola, mundo!' (Rust con VS Code) .

    También hay comandos Depurar y Ejecutar insertados dentro del editor de texto. Como alternativa, desde un símbolo del sistema en la carpeta rss_reader, escriba cargo run, que compilará y ejecutará el programa.

    los comandos Depurar y Ejecutar integrados en el editor de texto

    En el panel de terminal de VS Code , puedes ver que Cargo descarga y compila con éxito el crate windows , almacena en caché los resultados y los utiliza para que las compilaciones posteriores se completen en menos tiempo. A continuación, compila el ejemplo y lo ejecuta, mostrando una lista de títulos de entrada de blog.

    Lista de títulos de entradas de blog

Eso es tan sencillo como es programar Rust para Windows. Bajo el capó, sin embargo, se pone mucho esfuerzo en la creación de herramientas para que Rust pueda analizar .winmd archivos basados en ECMA-335 (Common Language Infrastructure o CLI) y también cumplir fielmente con la interfaz binaria de aplicaciones basada en COM (ABI) en tiempo de ejecución, considerando tanto la seguridad como la eficiencia.

Mostrar un cuadro de mensaje

Hemos dicho que Rust para Windows te permite llamar a cualquier API de Windows (pasada, presente y futura). Por lo tanto, en esta sección se mostrarán un par de cuadros de mensaje de Windows.

  1. Al igual que hicimos para el proyecto RSS, en el símbolo del sistema cd a la carpeta con los proyectos de Rust.

  2. Cree un proyecto denominado message_box y ábralo en VS Code:

    > cargo new message_box
    >     Created binary (application) `message_box` package
    > cd message_box
    > code .
    
  3. En VS Code, abra Cargo.tomly agregue las dependencias de Windows para este proyecto:

     # message_box\Cargo.toml
     ...
    
     [dependencies.windows]
     version = "0.43.0"
     features = [
         "Win32_Foundation",
         "Win32_UI_WindowsAndMessaging",
     ]
    
  4. Abra el archivo del proyecto src/main.rs y agregue las declaraciones use con los nuevos espacios de nombres, tal como se muestra a continuación. Y, por último, agregue código para llamar a las funciones MessageBoxA y MessageBoxW. Los documentos de la API de Windows se escriben principalmente teniendo en cuenta C/C++, por lo que resulta útil comparar los documentos de API con los documentos de las proyecciones de Rust en la caja de windows : MessageBoxA (Rust) y 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 puede ver, debemos usar estas API de Win32 en un unsafe bloque (consulte Bloques no seguros). ¡Anote también los macros s! y w!, que crean argumentos LPCSTR y LPCWSTR a partir de literales de cadena UTF-8 de Rust; de la misma manera que creamos un HSTRING con el macro h! para rss_reader. Rust es nativamente Unicode con cadenas UTF-8, por lo que el uso de las API Unicode de Windows (Wsufijo) es preferible a las API ANSI (sufijo A). Esto puede ser importante si usa texto no en inglés en el código.

Esta vez, cuando se compila y se ejecuta, Rust muestra dos cuadros de mensaje de Windows.