Skip to content

Commit

Permalink
featL parser basics
Browse files Browse the repository at this point in the history
  • Loading branch information
mrchantey committed Jan 14, 2025
1 parent 538bec7 commit e2314c6
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 129 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ categories.workspace = true
keywords.workspace = true

[features]
default = ["server", "rsx"]

rsx = ["dep:sweet_rsx"]
server = ["dep:sweet_server"]
parse = ["dep:sweet_parse"]
Expand Down
9 changes: 1 addition & 8 deletions crates/sweet_core/src/rsx/rsx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,5 @@ impl Rsx for RsxParts {
}

impl Rsx for () {
fn into_parts(self) -> RsxParts { Default::default() }
}
// impl Rsx<()> for () {
// fn into_rsx(self) -> RsxParts { Default::default() }
// }

pub trait IntoRsx {
fn into_rsx(self) -> impl Rsx;
fn into_parts(self) -> RsxParts { RsxParts::default() }
}
48 changes: 1 addition & 47 deletions crates/sweet_parse/src/parse_rsx/rsx_file_visitor.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
use crate::prelude::*;
use quote::ToTokens;
use syn::visit;
use syn::visit_mut;
use syn::visit_mut::VisitMut;
use syn::Expr;
use syn::ExprMacro;
use syn::ForeignItemMacro;
use syn::Stmt;



/// The rsx visitor is used by file (preprocessor) parsers.
Expand Down Expand Up @@ -58,9 +51,8 @@ impl<'a, P: RsxPlugin> RsxFileVisitor<'a, P> {

impl<'a, P: RsxPlugin> VisitMut for RsxFileVisitor<'a, P> {
fn visit_macro_mut(&mut self, item: &mut syn::Macro) {
// println!("item {:?}", item);
if P::path_matches(&item.path) {
match self.plugin.visit_rsx(item) {
match self.plugin.parse_rsx(&mut item.tokens) {
Ok(parts) => self.macros.push(parts),
Err(e) => self.errors.push(e),
}
Expand All @@ -70,42 +62,4 @@ impl<'a, P: RsxPlugin> VisitMut for RsxFileVisitor<'a, P> {
// visit nested
visit_mut::visit_macro_mut(self, item);
}


fn visit_stmt_mut(&mut self, stmt: &mut Stmt) {
// match &stmt {
// Stmt::Macro(stmt_mac) => {}
// Stmt::Expr(_, _) => {
// println!("expr {}", stmt.to_token_stream().to_string());
// }
// stmt => {
// println!("item {}", stmt.to_token_stream().to_string());
// }
// }
// visit nested
visit_mut::visit_stmt_mut(self, stmt);
}

// fn visit_macro_delimiter_mut(&mut self, item: &mut syn::MacroDelimiter) {
// println!("item {:?}", item);
// }
// fn visit_item_macro_mut(&mut self, item: &mut syn::ItemMacro) {
// println!("item {:?}", item);
// }
// fn visit_type_macro_mut(&mut self, item: &mut syn::TypeMacro) {
// println!("item {:?}", item);
// }
// fn visit_trait_item_macro_mut(&mut self, item: &mut syn::TraitItemMacro) {
// println!("item {:?}", item);
// }

// fn visit_expr_mut(&mut self, expr: &mut Expr) {
// println!("expr {:?}", expr);
// }
// fn visit_expr_macro_mut(&mut self, expr: &mut ExprMacro) {
// println!("expr {:?}", expr);
// }
// fn visit_foreign_item_macro_mut(&mut self, expr: &mut ForeignItemMacro) {
// println!("expr {:?}", expr);
// }
}
21 changes: 6 additions & 15 deletions crates/sweet_parse/src/parse_rsx/rsx_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ use super::RsxFileVisitor;
use super::RsxFileVisitorOut;
use super::WalkNodesOutput;
use proc_macro2::TokenStream;
use quote::ToTokens;
use rstml::node::CustomNode;
use rstml::node::KeyedAttribute;
use rstml::node::NodeBlock;
use rstml::node::NodeElement;
use syn::visit_mut::VisitMut;
use syn::Expr;
use syn::File;
use syn::Macro;





Expand All @@ -28,19 +24,14 @@ pub trait RsxPlugin: Sized {
Ok((file, visitor.into()))
}

/// entrypoint for inline (macro) parsing.
fn parse_tokens(
&mut self,
tokens: TokenStream,
) -> syn::Result<(TokenStream, WalkNodesOutput)> {
let mut mac: Macro = syn::parse2(tokens)?;
let output = self.visit_rsx(&mut mac)?;
Ok((mac.tokens.to_token_stream(), output))
}


/// entrypoint for inline (macro) parsing.
/// Called when visiting an rsx macro.
fn visit_rsx(&mut self, mac: &mut Macro) -> syn::Result<WalkNodesOutput>;
/// Mutated in place for efficient file parsing
fn parse_rsx(
&mut self,
tokens: &mut TokenStream,
) -> syn::Result<WalkNodesOutput>;

fn visit_block(&mut self, block: &NodeBlock, output: &mut WalkNodesOutput);
fn visit_event(
Expand Down
25 changes: 14 additions & 11 deletions crates/sweet_parse/src/parse_rsx/sweet_rsx_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use proc_macro2::TokenStream;
use quote::quote;
use quote::ToTokens;
use rstml::node::CustomNode;
Expand All @@ -8,7 +9,6 @@ use rstml::node::NodeAttribute;
use rstml::node::NodeBlock;
use rstml::node::NodeElement;
use rstml::node::NodeName;
use syn::Macro;

/// The sweet plugin for the rsx! macro.
/// Deliberately no default, any implementers of this trait
Expand Down Expand Up @@ -44,8 +44,11 @@ impl SweetRsxPlugin {


impl RsxPlugin for SweetRsxPlugin {
fn visit_rsx(&mut self, mac: &mut Macro) -> syn::Result<WalkNodesOutput> {
let (nodes, rstml_errors) = parse_rstml(mac.tokens.clone());
fn parse_rsx(
&mut self,
tokens: &mut TokenStream,
) -> syn::Result<WalkNodesOutput> {
let (nodes, rstml_errors) = parse_rstml(tokens.clone());
let output = WalkNodes::walk_nodes(self, nodes);
let WalkNodesOutput {
errors,
Expand All @@ -67,7 +70,7 @@ impl RsxPlugin for SweetRsxPlugin {
Default::default()
};

mac.tokens = syn::parse_quote! {{
*tokens = syn::parse_quote! {{
#errors
sweet::prelude::RsxParts {
rust: vec![#(#rust,)*],
Expand Down Expand Up @@ -179,11 +182,11 @@ mod test {
let mut plugin = SweetRsxPlugin::new_no_errors();
// macro with an event and block
// raw text nodes are trimmed
let mac = quote::quote! {
rsx!{<div onclick></div>}
let mut tokens = quote::quote! {
<div onclick></div>
};

let (tokens, out) = plugin.parse_tokens(mac).unwrap();
let out = plugin.parse_rsx(&mut tokens).unwrap();
let tokens_str = tokens.to_string();
// let tokens_str = prettyplease::unparse(
// &syn::parse_file(&tokens.to_string()).unwrap(),
Expand All @@ -198,10 +201,10 @@ mod test {
fn text_blocks() {
let mut plugin = SweetRsxPlugin::new_no_errors();
// raw text nodes are trimmed
let mac = quote::quote! {
let mut tokens = quote::quote! {
rsx!{<div>"the "{value}"th "<bold>value</bold> is {value}</div>}
};
let (_expr, out) = plugin.parse_tokens(mac).unwrap();
let out = plugin.parse_rsx(&mut tokens).unwrap();
expect(out.html)
.to_be(r#"<div rsx-id="0">the §th <bold>value</bold>is §</div>"#);
}
Expand All @@ -210,10 +213,10 @@ mod test {
fn child_component() {
let mut plugin = SweetRsxPlugin::new_no_errors();
// raw text nodes are trimmed
let mac = quote::quote! {
let mut tokens = quote::quote! {
rsx!{<body><Header>"sweet "<b/>as</b></Header></body>}
};
let (_expr, out) = plugin.parse_tokens(mac).unwrap();
let out = plugin.parse_rsx(&mut tokens).unwrap();
expect(out.html).to_be(r#"<body>§§sweet <b>as</>§§</body>"#);
}
}
1 change: 0 additions & 1 deletion crates/sweet_parse/tests/parse_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ mod test {
use forky::prelude::FsExt;
use forky::prelude::ReadFile;
use sweet::prelude::*;
use sweet_parse::prelude::*;

#[test]
fn works() {
Expand Down
24 changes: 16 additions & 8 deletions crates/sweet_rsx/macros/src/rsx/rsx_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// use super::empty_elements;
// use super::parse_nodes;
// use super::WalkNodes;

use quote::ToTokens;
use sweet_parse::prelude::RsxPlugin;
use sweet_parse::prelude::SweetRsxPlugin;

Expand All @@ -12,11 +10,21 @@ pub struct RsxMacro;

impl RsxMacro {
pub fn parse(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let tokens = syn::parse_macro_input!(tokens as syn::ItemMacro);
SweetRsxPlugin::new_with_errors()
.parse_tokens(tokens.to_token_stream())
.map(|(tokens, _)| tokens)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
let mut tokens: proc_macro2::TokenStream = tokens.into();
let result = SweetRsxPlugin::new_with_errors().parse_rsx(&mut tokens);

if let Err(err) = result {
let error = err.to_compile_error();
let tokens = quote::quote! {
#tokens
#error
};
let tokens: proc_macro::TokenStream = tokens.into();
return tokens;
}

let tokens: proc_macro::TokenStream = tokens.into();

tokens
}
}
7 changes: 6 additions & 1 deletion crates/sweet_server/src/server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ pub struct Server;
impl Server {
pub fn run(self, rsx: impl Rsx) {
let rsx = rsx.into_parts();
println!("todo run server for {:?}", rsx);
}

pub fn run_once(self, rsx: impl Rsx) {
let rsx = rsx.into_parts().into_parts();

todo!("todo run server for {:?}", rsx);
println!("todo run server for {:?}", rsx);
}
}
4 changes: 2 additions & 2 deletions crates/sweet_site/src/components/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ pub struct Counter {
}


impl IntoRsx for Counter {
fn into_rsx(self) -> impl Rsx {
impl Rsx for Counter {
fn into_parts(self) -> RsxParts {
let (value, set_value) = arc_signal(self.initial_value);
// rsx! {
// <div>
Expand Down
6 changes: 3 additions & 3 deletions crates/sweet_site/src/components/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use sweet::prelude::*;

pub struct HelloWorld;

impl IntoRsx for HelloWorld {
fn into_rsx(self) -> impl Rsx {
let planet = "mars";
impl Rsx for HelloWorld {
fn into_parts(self) -> RsxParts {
// let planet = "mars";
// rsx! {
// <button
// onclick={|_|{alert!(format!("hello {}!", planet))}}>
Expand Down
5 changes: 2 additions & 3 deletions crates/sweet_site/src/pages/index.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
pub use super::super::components::counter;
use sweet::prelude::*;

pub struct Index;

// maybe like IntoRoute or something
impl IntoRsx for Index {
fn into_rsx(self) -> impl Rsx {
impl Rsx for Index {
fn into_parts(self) -> RsxParts {
let initial_value = 200;
// rsx! {
// <h1>Counter</h1>
Expand Down
3 changes: 3 additions & 0 deletions crates/sweet_test/macros/src/macros/sweet_test_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use proc_macro2::TokenStream;
use quote::quote;
use syn::ItemFn;



/// The parser for the #[sweet_test] attribute
pub struct SweetTestAttr;

impl SweetTestAttr {
Expand Down
22 changes: 16 additions & 6 deletions examples/counter.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
use sweet::prelude::*;

fn main() { Server::default().run(rsx! {<Counter value=21/>}); }
fn main() {
// This example


Server::default().run(());
Server::default().run_once(Counter { value: 7 });
Server::default().run_once(Footer);
// TODO calling these.into_parts() and extending for children
Server::default().run_once(rsx! {<Counter />});
}

struct Counter {
value: i32,
}


impl IntoRsx for Counter {
fn into_rsx(mut self) -> impl Rsx {
impl Rsx for Counter {
fn into_parts(self) -> RsxParts {
rsx! {
<div> the value is {self.value} </div>
<button onclick={|_| {self.value += 1;}}>Increment</button>
<button onclick=|_| {}>Increment</button>
// <button onclick={|_| {sweet::prelude::log!("hello world")}}>Increment</button>
<Footer/>
}
}
Expand All @@ -20,8 +30,8 @@ impl IntoRsx for Counter {

struct Footer;

impl IntoRsx for Footer {
fn into_rsx(self) -> impl Rsx {
impl Rsx for Footer {
fn into_parts(self) -> RsxParts {
rsx! {
<footer>
<div>sweet as!</div>
Expand Down
Loading

0 comments on commit e2314c6

Please sign in to comment.