From 208c18c94a9dc1b7a36b28d4db383dd8487b1907 Mon Sep 17 00:00:00 2001 From: Valerio Ageno Date: Sun, 19 May 2024 12:22:56 +0200 Subject: [PATCH] feat: create base payload, request and response data structures --- crates/axum_bundler/src/bundle.rs | 17 ++++----- crates/tuono_lib/Cargo.toml | 4 ++ crates/tuono_lib/src/lib.rs | 13 ++++--- crates/tuono_lib/src/payload.rs | 24 ++++++++++++ crates/tuono_lib/src/request.rs | 38 +++++++++++++++++++ crates/tuono_lib/src/response.rs | 4 ++ crates/tuono_lib_macros/src/handler.rs | 22 +++++++---- .../src/components/RouterProvider.tsx | 4 +- 8 files changed, 102 insertions(+), 24 deletions(-) create mode 100644 crates/tuono_lib/src/payload.rs create mode 100644 crates/tuono_lib/src/request.rs create mode 100644 crates/tuono_lib/src/response.rs diff --git a/crates/axum_bundler/src/bundle.rs b/crates/axum_bundler/src/bundle.rs index d6bcf52d..ad2b3d8e 100644 --- a/crates/axum_bundler/src/bundle.rs +++ b/crates/axum_bundler/src/bundle.rs @@ -11,8 +11,9 @@ const AXUM_ENTRY_POINT: &'static str = r##" // File automatically generated // Do not manually change it +use axum::extract::Request; use axum::response::Html; -use axum::{http::Uri, routing::get, Router}; +use axum::{routing::get, Router}; use tower_http::services::ServeDir; use tuono_lib::{ssr, Ssr}; @@ -31,15 +32,13 @@ async fn main() { axum::serve(listener, app).await.unwrap(); } -async fn catch_all(uri: Uri) -> Html { - dbg!(&uri.path()); - let path = &uri.path(); +async fn catch_all(request: Request) -> Html { + let pathname = &request.uri(); + let headers = &request.headers(); - let payload = format!( - r#"{{ - "path": "{path}" - }}"# - ); + let req = tuono_lib::Request::new(pathname, headers); + + let payload = tuono_lib::Payload::new(&req, "".to_string()).client_payload(); let result = ssr::Js::SSR.with(|ssr| ssr.borrow_mut().render_to_string(Some(&payload))); diff --git a/crates/tuono_lib/Cargo.toml b/crates/tuono_lib/Cargo.toml index d7efe25a..0572445e 100644 --- a/crates/tuono_lib/Cargo.toml +++ b/crates/tuono_lib/Cargo.toml @@ -10,4 +10,8 @@ path = "src/lib.rs" [dependencies] ssr_rs = "0.5.1" +axum = "0.7.5" tuono_lib_macros = { path = "../tuono_lib_macros"} +serde = { version = "1.0.202", features = ["derive"] } +serde_json = "1.0" + diff --git a/crates/tuono_lib/src/lib.rs b/crates/tuono_lib/src/lib.rs index f2694b25..21c82c0d 100644 --- a/crates/tuono_lib/src/lib.rs +++ b/crates/tuono_lib/src/lib.rs @@ -1,8 +1,11 @@ +mod payload; +mod request; +mod response; + pub mod ssr; + +pub use payload::Payload; +pub use request::Request; +pub use response::Response; pub use ssr_rs::Ssr; pub use tuono_lib_macros::handler; - -pub enum Response { - Redirect(String), - Props(String), -} diff --git a/crates/tuono_lib/src/payload.rs b/crates/tuono_lib/src/payload.rs new file mode 100644 index 00000000..30b632e3 --- /dev/null +++ b/crates/tuono_lib/src/payload.rs @@ -0,0 +1,24 @@ +use serde::Serialize; + +use crate::request::Location; +use crate::Request; + +#[derive(Serialize)] +/// This is the data shared to the client +pub struct Payload<'a> { + router: Location<'a>, + props: String, +} + +impl<'a> Payload<'a> { + pub fn new(req: &Request<'a>, props: String) -> Payload<'a> { + Payload { + router: req.location(), + props, + } + } + + pub fn client_payload(&self) -> String { + serde_json::to_string(&self).unwrap() + } +} diff --git a/crates/tuono_lib/src/request.rs b/crates/tuono_lib/src/request.rs new file mode 100644 index 00000000..0210aef9 --- /dev/null +++ b/crates/tuono_lib/src/request.rs @@ -0,0 +1,38 @@ +use serde::Serialize; +use std::collections::HashMap; + +use axum::http::{HeaderMap, Uri}; + +#[derive(Debug)] +pub struct Request<'a> { + uri: &'a Uri, + headers: &'a HeaderMap, +} + +/// Location must match client side interface +#[derive(Serialize, Debug)] +pub struct Location<'a> { + href: String, + pathname: &'a str, + search: HashMap, + search_str: &'a str, + /// Server does not need it. Will be hanlder client side + hash: &'a str, +} + +impl<'a> Request<'a> { + pub fn new(uri: &'a Uri, headers: &'a HeaderMap) -> Request<'a> { + Request { uri, headers } + } + + pub fn location(&self) -> Location<'a> { + Location { + href: self.uri.to_string(), + pathname: &self.uri.path(), + // TODO: hanler search map + search: HashMap::new(), + search_str: &self.uri.query().unwrap_or(""), + hash: "", + } + } +} diff --git a/crates/tuono_lib/src/response.rs b/crates/tuono_lib/src/response.rs new file mode 100644 index 00000000..17abd054 --- /dev/null +++ b/crates/tuono_lib/src/response.rs @@ -0,0 +1,4 @@ +pub enum Response { + Redirect(String), + Props(String), +} diff --git a/crates/tuono_lib_macros/src/handler.rs b/crates/tuono_lib_macros/src/handler.rs index 04a51a3d..c1844b1c 100644 --- a/crates/tuono_lib_macros/src/handler.rs +++ b/crates/tuono_lib_macros/src/handler.rs @@ -8,25 +8,31 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream { let fn_name = item.clone().sig.ident; quote! { - use tuono_lib::Response; use axum::response::Html; - use axum::http::Uri; - use tuono_lib::ssr; #item - pub async fn route(uri: Uri) -> Html { - println!("Custom handler"); - let props = #fn_name(); + pub async fn route(request: axum::extract::Request) -> Html { + println!("Custom handler"); + let pathname = &request.uri(); + let headers = &request.headers(); + + let req = tuono_lib::Request::new(pathname, headers); + + let props = #fn_name(&req); + + let payload = tuono_lib::Payload::new(&req, "".to_string()).client_payload(); + + dbg!(&payload); let res = match props { - Response::Props(val) => ssr::Js::SSR.with(|ssr| ssr.borrow_mut().render_to_string(Some(val.as_str()))), + tuono_lib::Response::Props(val) => tuono_lib::ssr::Js::SSR.with(|ssr| ssr.borrow_mut().render_to_string(Some(&payload))), _ => Ok("500 Internal server error".to_string()) }; match res { Ok(html) => Html(html), - _ => Html("500".to_string()) + _ => Html("500 internal server error".to_string()) } } diff --git a/packages/tuono-router/src/components/RouterProvider.tsx b/packages/tuono-router/src/components/RouterProvider.tsx index 074082d4..0c084cea 100644 --- a/packages/tuono-router/src/components/RouterProvider.tsx +++ b/packages/tuono-router/src/components/RouterProvider.tsx @@ -44,7 +44,7 @@ interface RouterProviderProps { } interface ServerProps { - path: string + router: Location } const initRouterStore = (props?: ServerProps): void => { @@ -52,7 +52,7 @@ const initRouterStore = (props?: ServerProps): void => { if (typeof window === 'undefined') { updateLocation({ - pathname: props?.path || '', + pathname: props?.router.pathname || '', hash: '', href: '', searchStr: '',