Crate lol_async

source ·
Expand description

This crate is an effort to adapt cloudflare/lol-html for an async context. Unfortunately, due to lol-html’s design, the wrapped api is not ideal. In particular, the lol_html::HtmlRewriter is !Send, which means that we have some contortions in order to use this library in an async context that expects most futures to be Send. This crate addresses this by returning two types: A LolFuture that must be polled on whatever thread calls rewrite and a LolReader that is [AsyncRead] and can be moved around and sent between threads as needed.

Due to this design, it is necessary to poll the LolFuture in addition to reading from the LolReader

Improvements

Improvements to the design of this crate are very welcome. I don’t have a lot of experience working around !Send types in an async context, and although this crate achieved the result I needed, I hate it. Please open a PR or write a better crate! Alternatively, if you know someone at cloudflare, maybe arms can be twisted to adapt lol-html for async rust.

use lol_async::html::{element, html_content::ContentType, Settings};

let (fut, mut reader) = lol_async::rewrite(
    Cursor::new(r#"<html>
<head><title>hello lol</title></head>
<body><h1>hey there</h1></body>
</html>"#),
    Settings {
        element_content_handlers: vec![element!("h1", |el| {
            el.append("<span>this was inserted</span>", ContentType::Html);
            Ok(())
        })],
        ..Settings::default()
    }
);

let handle = your_async_executor::spawn_local(fut);

let mut buf = String::new();
reader.read_to_string(&mut buf).await?;

handle.await?;
assert_eq!(buf, r#"<html>
<head><title>hello lol</title></head>
<body><h1>hey there<span>this was inserted</span></h1></body>
</html>"#);

Re-exports

Structs

  • await this Future to drive the html rewriting process. The LolFuture contains the HtmlRewriter and as a result is !Send, so it must be spawned locally.
  • An [AsyncRead] type that will yield the rewritten html. LolReader is Send, allowing it to be used on a different thread from the paired LolFuture. Please note that reading from LolReader does not drive the LolHtml rewriter. Awaiting the LolFuture is also necessary.

Functions

  • This function is the primary entrypoint for lol-async. It takes a data Source that is [AsyncRead] and a Settings that describes the desired rewriting logic. It returns a !Send LolFuture future that drives the rewriter on the current thread and a LolReader that is Send and can be used anywhere an [AsyncRead] would be used. The html content yielded by the LolReader will be rewritten according to the rules specified in the Settings.