diff options
author | Peter Cai <[email protected]> | 2020-04-18 16:35:38 +0800 |
---|---|---|
committer | Peter Cai <[email protected]> | 2020-04-18 16:35:38 +0800 |
commit | 10339daf09042e1c548e09619aee0ff8305cb617 (patch) | |
tree | e2035d4c3269f2fd6922d3e04b289bc9b8f67f19 | |
parent | 994da996bcfea9c8b0d44bb7306101dfa83378a8 (diff) | |
download | paprika-10339daf09042e1c548e09619aee0ff8305cb617.tar.gz |
blog: refactor: rewrite more transform as iterator operations
-rw-r--r-- | src/blog.rs | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/src/blog.rs b/src/blog.rs index 7a36492..723e3a8 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -9,6 +9,7 @@ use crate::utils::*; use js_sys::{JsString, RegExp}; use pulldown_cmark::*; use serde::{Serialize, Deserialize}; +use std::future::Future; use std::vec::Vec; use wasm_bindgen::JsCast; use wasm_bindgen::closure::Closure; @@ -231,6 +232,22 @@ impl PostContentCache { } } + fn transform_tags<'ev>( + parser: impl 'ev + Iterator<Item = Event<'ev>> + ) -> impl 'ev + Iterator<Item = impl Future<Output = Event<'ev>>> { + parser.map(|mut ev| { + async { + match ev { + Event::Start(ref mut tag) | Event::End(ref mut tag) => { + Self::transform_tag(tag).await; + ev + }, + _ => ev + } + } + }) + } + fn transform_code_block_highlight<'iter, 'ev>( parser: impl Iterator<Item = Event<'ev>> ) -> impl Iterator<Item = Event<'ev>> { @@ -309,26 +326,20 @@ impl PostContentCache { // Despite the signature, this function BLOCKS // async only comes from digesting via SubtleCrypto pub async fn render(post: &Post) -> PostContentCache { - // We have to first collect all events into a vector - // because we need to asynchronously transform the events - // which could not be done through mapping on iterators - let mut parser: Vec<Event> = Parser::new_ext(&post.content, Options::all()).collect(); - for ev in parser.iter_mut() { - match ev { - Event::Start(tag) | Event::End(tag) => { - Self::transform_tag(tag).await; - }, - _ => () - }; - } - - // Now some pure iterator operations - let parser = parser.into_iter(); + let parser = Parser::new_ext(&post.content, Options::all()); // Apply code highlighting via Highlight.js let parser = Self::transform_code_block_highlight(parser); + // Apply async tag transform (resulting in an iterator of Futures) + let parser = Self::transform_tags(parser); + + // Await on every Future in the queue to convert them back as Events + let mut events: Vec<Event> = vec![]; + for ev in parser { + events.push(ev.await); + } let mut html_output = String::new(); - html::push_html(&mut html_output, parser); + html::push_html(&mut html_output, events.into_iter()); html_output = Self::transform_html(html_output); PostContentCache { uuid: post.uuid.clone(), |