Pitasi / rscx

Rust Server Components. JSX-like syntax and async out of the box.
https://rscx.dev/
MIT License
64 stars 6 forks source link

map_fragment and collect_fragment don't work with custom element children #13

Open cameronbraid opened 10 months ago

cameronbraid commented 10 months ago
{data.into_iter().map_fragment(|item| html! {
    <CustomElement/>
})}

errors with 'await' is only allowed inside 'async' functions and blocks

I am experimenting with the following trait and impl


#[async_trait]
pub trait MapFragmentAsyncExt<V> {
  async fn map_fragment<F, B, C>(self, mut f: F) -> String
  where
      Self: Sized,
      F: FnMut(V) -> C + std::marker::Send,
      C: Future<Output = B> + std::marker::Send,
      B: ToString,
      V: std::marker::Send
  ;
}

#[async_trait]
impl<V> MapFragmentAsyncExt<V> for Vec<V>
{
  async fn map_fragment<F, B, C>(self, mut f: F) -> String
  where
      Self: Sized,
      F: FnMut(V) -> C + std::marker::Send,
      C: Future<Output = B> + std::marker::Send,
      B: ToString,
      V: std::marker::Send
  {
    use futures::stream::StreamExt;

    let mut out  = Vec::with_capacity(self.len());
    let mut stream = futures::stream::iter(self);
    while let Some(v) = stream.next().await {
      let c = f(v).await;
      out.push(c.to_string());
    }
    out.into_iter().collect::<Vec<_>>().join("")
  }
}

which allows the following :

{data.map_fragment(|item| async { html! {
    <CustomElement/>
}}).await}

It moves data, and a bit awkward with the bracketing and .await but works none the less

cameronbraid commented 10 months ago

Another though on this.

Currently if I write my compoent fn as non async, it gets converted to async.

I don't need async components, so if the [component] macro could preserve my non async then I would be happy

cameronbraid commented 10 months ago

Hrm, I just realised that this can't be done. Since at the callsite for the using custom element <CustomElement/> there is no way to know if the custom element is async or not and therefore know if .await sholud be added