Skip to content

Commit

Permalink
⚗️ Try to write generate_app macros.
Browse files Browse the repository at this point in the history
But the charactor '#' cannot write in macro_rules' output...
Sucks...
  • Loading branch information
langyo committed Nov 8, 2023
1 parent 475512f commit 23d6a1e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
16 changes: 8 additions & 8 deletions packages/proto-macros/tests/genereate_app.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
#[cfg(test)]
mod test {
use hikari_proto::generate_app;

fn generate() {
generate_app! {
#[routes]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum Route {
#[at("/")]
Portal { recommend_list: Vec<String> }

#[at("/u/:id")]
#[at("/:id")]
#[url_params({ id: String })]
Personal { id: String, name: String, email: String }

#[at("/t/:id")]
#[url_params({ id: String })]
Thread { id: String, title: String, content: String, comments: Vec<String> }

#[not_found]
#[at("/404")]
NotFound
}

#[global_state]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct Theme {
pub primary_color: String,
pub secondary_color: String,
}

#[global_state]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct UserToken {
pub token: String,
Expand All @@ -39,12 +35,16 @@ mod test {

#[test]
fn render_at_client() {
generate().render_to_element("#root");
generate().hydrate(web_sys::window()?.document()?.get_element_by_id("_root")?);
}

#[test]
fn render_at_server() {
generate().render_to_string();
generate().render_to_string(Route::Personal {
id: "114514",
name: "homo",
email: "[email protected]",
});

let stream = generate().render_to_stream();
}
Expand Down
1 change: 1 addition & 0 deletions packages/proto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod macros;

pub use macros::generate_app::*;
pub use macros::register_routes::*;
56 changes: 56 additions & 0 deletions packages/proto/src/macros/generate_app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#[macro_export]
macro_rules! generate_structs {
($(#[$meta:meta])* $vis:vis struct $name:ident { $($field:tt)* } $($rest:tt)*) => {
$(#[$meta])*
$vis struct $name {
$($field)*
}
generate_structs! { $($rest)* }
};
() => {}
}

#[macro_export]
macro_rules! generate_app {
(
$(#[$route_meta:meta])*
$route_vis:vis enum $route_enum:ident {
$(
$(#[$($variant_meta:meta)*])*
$variant:ident $( { $( $field:ident : $field_ty:ty ),* } )?
)*
}

$($rest:tt)*
) => {
#[derive(yew_router::Routable)]
$(#[$route_meta])*
$route_vis enum $route_enum {
$(
$(#[$($variant_meta)*])*
$variant $( { $( $field : $field_ty ),* } )?
)*
}

generate_structs! { $($rest)* }

#[cfg(feature = "web")]
impl $props_enum {
$props_vis fn hydrate(element: web_sys::Element) -> Result<Self, JsValue> {
let props_json = element
.get_attribute("_props")
.ok_or_else(|| JsValue::from_str("Missing _props attribute"))?;
let props: Self = serde_json::from_str(&props_json)?;
Ok(props)
}
}

#[cfg(not(feature = "web"))]
impl $props_enum {
$props_vis fn render_to_string(&self) -> Result<String, JsValue> {
let props_json = serde_json::to_string(self)?;
Ok(props_json)
}
}
};
}
1 change: 1 addition & 0 deletions packages/proto/src/macros/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod generate_app;
pub mod register_routes;

0 comments on commit 23d6a1e

Please sign in to comment.