diff --git a/benches/benches/benchmark.rs b/benches/benches/benchmark.rs
index 6075708..4504147 100644
--- a/benches/benches/benchmark.rs
+++ b/benches/benches/benchmark.rs
@@ -118,7 +118,6 @@ fn horrorshow_many_dyn_attrs() -> String {
}
fn rscx_many_dyn_attrs() -> String {
- use rscx::EscapeAttribute;
let value: i32 = 42;
rscx::html! {
diff --git a/rscx-macros/src/lib.rs b/rscx-macros/src/lib.rs
index a70b9e4..d1a1f81 100644
--- a/rscx-macros/src/lib.rs
+++ b/rscx-macros/src/lib.rs
@@ -1,7 +1,6 @@
use std::collections::HashSet;
use proc_macro::TokenStream;
-use proc_macro2::{Literal, TokenTree};
use proc_macro2_diagnostics::Diagnostic;
use quote::{quote, quote_spanned, ToTokens};
use rstml::{
@@ -75,7 +74,7 @@ fn process_nodes<'n>(
#(#errors;)*
// Make sure that "enum x{};" and "let _x = crate::element;" can be used in this context
#(#docs;)*
- format!(#html_string, #(#values),*)
+ format!(#html_string, #(rscx::FormatWrapper::new(#values)),*)
}
}
}
@@ -212,11 +211,7 @@ fn walk_nodes<'a>(nodes: &'a Vec) -> WalkNodesOutput<'a> {
out.static_format.push_str(&text.value_string());
}
Node::RawText(text) => {
- out.static_format.push_str("{}");
- let tokens = text.to_string_best();
- let literal = Literal::string(&tokens);
-
- out.values.push(TokenTree::from(literal).into());
+ out.static_format.push_str(&text.to_string_best());
}
Node::Fragment(fragment) => {
let other_output = walk_nodes(&fragment.children);
@@ -227,8 +222,10 @@ fn walk_nodes<'a>(nodes: &'a Vec) -> WalkNodesOutput<'a> {
out.values.push(comment.value.to_token_stream());
}
Node::Block(block) => {
+ let block = block.try_block().unwrap();
+ let stmts = &block.stmts;
out.static_format.push_str("{}");
- out.values.push(block.to_token_stream());
+ out.values.push(quote!(#(#stmts)*));
}
}
}
@@ -277,7 +274,8 @@ fn walk_attribute(attribute: &KeyedAttribute) -> (String, Option Result<(), Box> {
+ let app = app().await;
+ println!("{}", app);
+ Ok(())
+}
+
+// simple function returning a String
+// it will call the Items() function
+async fn app() -> String {
+ let s = Some("ul { color: red; }");
+ let none: Option<&str> = None;
+ html! {
+
+
+
+
+
+
+ { none }
+ // call a component with no props
+
+
+ }
+}
diff --git a/rscx/src/format_wrapper.rs b/rscx/src/format_wrapper.rs
new file mode 100644
index 0000000..c7a3bd8
--- /dev/null
+++ b/rscx/src/format_wrapper.rs
@@ -0,0 +1,20 @@
+use std::fmt::{self, Display};
+
+use crate::render::Render;
+
+pub struct FormatWrapper {
+ inner: T,
+}
+
+impl FormatWrapper {
+ pub fn new(inner: T) -> Self {
+ Self { inner }
+ }
+}
+
+impl Display for FormatWrapper {
+ #[inline(always)]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.inner.render(f)
+ }
+}
diff --git a/rscx/src/lib.rs b/rscx/src/lib.rs
index 572cdd7..a699b4c 100644
--- a/rscx/src/lib.rs
+++ b/rscx/src/lib.rs
@@ -5,6 +5,8 @@ pub use attributes::*;
#[cfg(feature = "axum")]
pub mod axum;
pub mod context;
+pub mod format_wrapper;
+pub mod render;
pub extern crate rscx_macros;
use std::future::Future;
@@ -14,6 +16,7 @@ pub use rscx_macros::*;
pub extern crate typed_builder;
pub extern crate html_escape;
+pub use format_wrapper::FormatWrapper;
use async_trait::async_trait;
use futures::future::join_all;
diff --git a/rscx/src/render.rs b/rscx/src/render.rs
new file mode 100644
index 0000000..06ca52c
--- /dev/null
+++ b/rscx/src/render.rs
@@ -0,0 +1,142 @@
+use std::{
+ borrow::Cow,
+ convert::Infallible,
+ env::VarError,
+ fmt,
+ io::ErrorKind,
+ net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
+ num::{
+ NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
+ NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
+ },
+ rc::Rc,
+ sync::{
+ mpsc::{RecvTimeoutError, TryRecvError},
+ Arc,
+ },
+};
+
+pub trait Render {
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
+}
+
+macro_rules! impl_render_for_basic_types {
+ ($($t:ty)*) => ($(
+ impl Render for $t {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+ }
+ )*)
+}
+
+impl_render_for_basic_types! {
+ Infallible
+ VarError
+ ErrorKind
+ IpAddr
+ SocketAddr
+ RecvTimeoutError
+ TryRecvError
+ bool
+ char
+ f32
+ f64
+ i8
+ i16
+ i32
+ i64
+ i128
+ isize
+ u8
+ u16
+ u32
+ u64
+ u128
+ usize
+ Ipv4Addr
+ Ipv6Addr
+ SocketAddrV4
+ SocketAddrV6
+ NonZeroI8
+ NonZeroI16
+ NonZeroI32
+ NonZeroI64
+ NonZeroI128
+ NonZeroIsize
+ NonZeroU8
+ NonZeroU16
+ NonZeroU32
+ NonZeroU64
+ NonZeroU128
+ NonZeroUsize
+ String
+ str
+}
+
+impl Render for Cow<'_, B>
+where
+ B: Render + ToOwned,
+ ::Owned: Render,
+{
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match *self {
+ Cow::Borrowed(ref b) => Render::render(b, f),
+ Cow::Owned(ref o) => Render::render(o, f),
+ }
+ }
+}
+
+impl Render for Box {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Render::render(&**self, f)
+ }
+}
+
+impl Render for &T {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Render::render(&**self, f)
+ }
+}
+
+impl Render for &mut T {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Render::render(&**self, f)
+ }
+}
+
+impl Render for Rc {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Render::render(&**self, f)
+ }
+}
+
+impl Render for Arc {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Render::render(&**self, f)
+ }
+}
+
+impl Render for Option {
+ #[inline(always)]
+ fn render(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if let Some(inner) = self {
+ inner.render(f)
+ } else {
+ Ok(())
+ }
+ }
+}
+
+impl Render for () {
+ #[inline(always)]
+ fn render(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
+ Ok(())
+ }
+}
diff --git a/website/src/main.rs b/website/src/main.rs
index 77e7a6e..c251c48 100644
--- a/website/src/main.rs
+++ b/website/src/main.rs
@@ -5,7 +5,7 @@ use std::{
};
use csm::csm;
-use rscx::{component, html, EscapeAttribute};
+use rscx::{component, html};
use rscx_mdx::mdx::{Mdx, MdxComponentProps};
#[tokio::main]