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 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(
<head><title>hello lol</title></head>
<body><h1>hey there</h1></body>
    Settings {
        element_content_handlers: vec![element!("h1", |el| {
            el.append("<span>this was inserted</span>", ContentType::Html);

let handle = your_async_executor::spawn_local(fut);

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

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


  • pub use lol_html as html;


  • 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.


  • 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.