Yew, crea webapps al estilo Angular/React en Rust

Hoy os traigo una librería muy potente y muy útil, ahora que Rust compila a WebAssembly de forma nativa. Se trata de Yew, una librería para diseñar frontends, single-page-applications y en general, una librería que es una alternativa a Angular, React, Vue y Elm.

En particular, Yew se basa en The Elm Architecture, por lo que los usuarios de Elm serán los que encuentren más familiar a Yew.

Yew significa tejo. He aquí uno de los tejos más famosos de Valladolid, en la plaza del Viejo Coso

Instalar cargo-web y el soporte a WebAssembly

Antes de empezar a programar necesitaremos instalar un plugin para Cargo, llamado cargo-web, que nos ayudará en el desarrollo web con Rust. Por otro lado, hace falta instalar el soporte de Rust a WebAssembly. Existen tres opciones actualmente: asmjs-unknown-emscripten, wasm32-unknown-emscripten y wasm32-unknown-unknown. Para los primeras opciones hace falta tener instalado Emscripten. Para la última, no hace falta nada, por lo que es mi opción recomendada. Por otro lado, wasm32 significa WebAssembly y asmjs es asm.js, que es simplemente JavaScript y será compatible con más navegadores.

The Elm Architecture

Los principios de The Elm Architecture se basan en: modelo, mensajes, actualización y vista.

Para este tutorial vamos a hacer la típica aplicación de una lista donde guardamos notas. Nuestro modelo se va a componer de una lista de tareas, para simplificar, pongamos que una tarea es simplemente un String y un ID. Entonces también nos hará falta almacenar un contador para ir poniendo IDs. También, al tener un campo de texto, nos hará falta una variable para ir almacenando temporalmente lo que escribe el usuario.

Lo siguiente es diseñar los mensajes. Los mensajes interactúan con el modelo y desencadenan una actualización de la vista. En esta aplicación solo nos hacen falta dos mensajes: añadir mensaje y borrar mensaje. Pero como tenemos un campo de texto, tenemos que introducir un mensaje Change y siempre viene bien un mensaje que no haga nada.

Una vez hecho esto pasamos a crear la función update, en la que hacemos distintas cosas según el mensaje que recibamos.

Así pues, si se lanza un mensaje Msg::Add lo que hacemos es copiar el valor de la variable temporal input, crear una nueva tarea con su ID y añadirla a la lista de tareas. Ya está. Yew mágicamente actualizará la página para reflejar que la lista de tareas ha sido modificada. Lo mismo pasa con Remove.

Ahora vamos a las vistas. Una vista es una función que devuelve Html<Msg> y se pueden componer varias funciones así. En nuestro caso, tenemos una vista principal donde se ve un campo de texto y un sitio donde se ejecuta un bucle for con las tareas del modelo. Y a cada tarea se le aplica la vista view_task.

La macro html! nos permite escribir HTML directamente en Rust, con algunas diferencias (¡prestad atención a las comas!). También nos permite introducir código Rust (entre llaves) y closures (observad onclick, oninput y onkeypress).

Finalmente en el método main, inicializamos el modelo y llamamos a program, que empieza a ejecutar Yew.

El código final queda así.

Ejecutando la aplicación web

Usando cargo web, es muy sencillo generar la aplicación web. Simplemente ejecuta:

El resultado, se montará en un mini servidor web. Si accedes a la URL que indica Cargo con tu navegador web, verás algo similar a esto:

Añade items y bórralos. Observa como la aplicación funciona perfectamente.

Distribuyendo la aplicación

Realmente cargo web ha hecho muchas cosas por nosotros. Si nosotros queremos usar Yew en la vida real, no usaremos cargo web. Para ello, compilamos la aplicación web:

Y accedemos a la carpeta target/wasm32-unknown-unknown/release. Allí encontraremos dos archivos que vamos a necesitar. Uno acabado en .js y otro acabado en .wasm. Ambos ficheros deberemos copiarlos donde queramos usarlos. Por último, será necesario un fichero HTML. En el fichero HTML solo hace falta cargar el fichero JS. Yew hará el resto.

Si quieres saber más, puedes descargarte el código de ejemplo que se encuentra en GitHub.

Leer y escribir JSON en Rust con Serde

JSON es un formato muy popular para guardar y transmitir información. En Rust podemos leer y escribir JSON de forma transparente gracias a Serde. Serde es una librería para Rust, que permite transformar las structs nativas de Rust en ficheros JSON, YAML, BSON, MsgPack, XML y viceversa. Serde está compuesto de varios plugins, uno para cada formato de archivo, así que vamos a necesitar el plugin de JSON. Es lo que se dice serializar (guardar) y deserializar (leer).

Deserializando JSON con Serde

Para deserializar necesitamos primero definir el struct en Rust que se corresponde al JSON que vamos a cargar. Además, hay que incluir una cláusula derive e indicar que derivamos Deserializable.

Una vez hecho eso podemos realizar la transformación con Serde. Serde admite varios métodos de entrada. En mi caso voy a usar from_reader, que permite transformar desde cualquier std::io::Read. También se podría usar from_str, que permite leer desde un String.

Así pues un programa que lea Landmarks de un fichero JSON como este:

Quedaría así:

Nótese como usamos Vec<Landmark> para indicar que vamos a cargar un JSON que es un array de Landmarks.

Serializar JSON

Ahora si queremos generar un archivo JSON es muy sencillo. Simplemente marcamos Serialize en la misma estructura que queramos serializar. Posteriormente en Serde podemos utilizar diferentes métodos, como to_writer o to_string.

Personalizando la serialización y la deserialización

Serde permite a través de atributos, definir de forma precisa que ocurre con los elementos. En caso de no poner nada, por ejemplo, Serde usará los nombres del struct de Rust en los ficheros y si hay elementos de más, en el fichero al leer, los ignorará.

Por ejemplo, si queremos que en el fichero JSON, en vez de tener name sea nombre, podemos usar rename.

Podemos también no querer guardar algún elemento del struct, usamos skip.


Si queremos que Serde falle en caso de que en el JSON haya más campos de los que hemos definido, usamos deny_unkown_fields.

Y si queremos que el nombre del struct sea distinto al que crea oportuno Serde, podemos redefinirlo también:

Por último, mencionar que Serde permite serializar/deserializar cosas más complejas, con otros structs, con vectores, con HashMap, entre sus elementos,… Lo único que tendrá que pasar es que esas estructuras a su vez sean serializables/deserializables con Serde (es decir, hayan puesto derive(Serialize,Deserialize)).

Gana dos entradas dobles para “Bugs” en el Museo Reina Sofía

En enero de 2018, el Museo Reina Sofía de Madrid acogerá la exposición Bugs, una exposición dedicada a esas obras de arte que muchas veces pasan inadvertidas, los bugs.

En esta exposición, que se expondrá hasta el 1 de abril de 2018, podremos ver algunos de los máximos exponentes de este estilo artístico surgido a finales del siglo XX y muy popular en el siglo XXI. Como yo mismo he formado parte del comité de selección de obras, tengo el honor de regalar dos entradas dobles para la exposición.

«Queremos reunir en un mismo edificio todas las sensaciones que han provocado a los usuarios. Rabia, indignación, ira y soledad.» dice Sara Echeverría, directora de exposiciones temporales del Reina Sofía y buena amiga.

Algunas de las obras, más destacadas son:

Pantalla azul de Windows sobre monitor Samsung
Pantalla azul de Windows sobre monitor LG y cables desordenados

 

Pantalla azul de Windows rotada PI/2 radianes en aeropuerto

«Las pantallas azules nos transmiten finalidad. Nos hacen ver que todo es efímero. Todo nuestro trabajo, nuestra huella en la humanidad, puede desvanecerse con un simple error de driver. Al final, no somos nada. Una gota más, del océano inmenso.» dice Bill Gates, que fue invitado para preparar la exposición. «Creemos que Bill Gates es uno de los maestros en el arte del bug, su ayuda nos ha sido indispensable para encontrar el enfoque filosófico que buscábamos».

Final de un programa en LISP

«A mí siempre me han atraído los paréntesis de LISP. Era como algo sexual. Sentía orgasmos al descubrir que podía meter más paréntesis todavía.» Y es que en la exposición también se verán obras proclives a bugs como los paréntesis de LISP o la sagrada trinidad de JavaScript.

«JavaScript iba a llenar bastantes salas, así que solamente hemos elegido lo mejor. Ha sido difícil, porque cada día salen nuevos e impresionantes bugs, en cada nueva librería o framework. Habrá que estar atentos a ellos, porque son el futuro de los bugs»

También se ha dejado una sala especial a los ciberataques, que este año han sabido aprovechar con mucha intelegencia bugs de los sistemas operativos más conocidos. ¿Cómo olvidar el WannaCry de Edvard Munch?

WannaCry, de Edvard Munch

Pero no sería  una exposición completa sin contar con bugs como el efecto 2000 o el lanzamiento del cohete Ariane 5 (esas cosas pasan por usar ints de 16 bits en un cohete).

Si queréis participar para ganar una de las dos entradas dobles para ver la exposición, solo tenéis que hacer click aquí.

¡Feliz navidad y próspero 2018! (con fractales)

Feliz Navidad! Si estás leyendo esto, darte las gracias por seguir leyendo este blog. Me alegro mucho de tener cada vez más lectores y es algo que me anima a escribir más y más. En este especial navideño disfrutaremos de éxitos musicales de la navidad, veremos como hacer un fractal muy navideño en Rust y os pediré vuestra opinión.

Comenzamos con In Dulci Jubilo y este cover de Giuliano Ferrace Leanza

El fractal de Koch

Helge von Koch fue un matemático sueco que en 1904 publica un artículo sobre la que desde entonces se llamaría curva de Koch. Se trata de una curva, generada con unas reglas muy simples. La idea fundamental es que se parte de una recta, que se divide en tres trozos iguales. El trozo del medio se sustituye por un triángulo equilátero. Entonces la curva recorre el primer trozo, sube el triángulo, baja el triángulo y continúa recto.

Si ahora en cada uno de los cuatro trozos rectos aplicamos la misma curva de Koch obtenemos esto:

Según la terminología de Mandelbrot, este fractal es un teragón. Si ahora en vez de aplicar esto sobre una recta, lo hacemos sobre un triángulo equilátero con sus tres trozos rectos iguales, ¿qué obtenemos?

Turtle, una librería de Rust para gráficos tortuga

Quizá entre mis lectores haya alguno que aprendió a programar con LOGO. Una de las características de LOGO era que disponía de una tortuga con la que íbamos dibujando según nos movíamos. Esta manera de dibujar, no es óptima en rendimiento puro, pero es ideal para fractales y para enseñar a programar. Python incorpora en su librería estándar el módulo turtle y en Rust está a punto de salir una librería que soporta una API similar llamada turtle.

Lo primero que tenemos que hacer es definir la curva de Koch con turtle.

Con esto nos valdría, pero no es recursivo. Necesitamos poder aplicar la curva de Koch en nuestras rectas (donde hacemos forward) de forma recursiva. Pero si lo hacemos recursivo de forma infinita no acabará nunca, es por ello que tenemos que indicar cuantos niveles de recursividad queremos.

Esto ya tiene más sentido. Ahora juntemos todo lo necesario:

Si compilamos y ejecutamos esto con Cargo:

Y aquí tenemos al copo de nieve de Koch.

Tenéis el proyecto completo en GitHub: https://github.com/aarroyoc/fractal_koch_rust

Fractal (bis)

Otro fractal muy interesante que programé mientras estaba haciendo el copo de nieve fue este otro. Desconozco si tiene nombre. Es algo más complejo de implementar y lo de los colores me dio bastantes dolores de cabeza hasta que encontré una progresión bella.

Su código es (en este caso Python):

 

Vuestra opinión

Ahora os pido que me déis vuestra opinión sobre el blog. Usad los comentarios de debajo y contadme: ¿Cuál es el mayor problema del blog?, ¿crees que los contenidos salen con frecuencia suficiente y necesaria?, ¿los temas son interesantes?, ¿me voy mucho por las ramas?, … Todo esto lo tendré en cuenta de cara al año que viene.

Aprovecho para recordar que podéis suscribiros a la lista de correo para que os llegue un nuevo correo con cada post, podeís suscribiros al blog por RSS, hay un canal de Telegram y una página en Facebook. En Twitter, GNU Social e Instagram solo tengo perfiles personales, pero si os interesa, allí estoy. Por último en Google+ todavía sigo mandando los artículos.

Si os parece que me merezco una caña, siempre puedes donar usando PayPal, criptodivisas, tu apartamento en Comillas, …

Sin más, feliz próspero año 2018