feat: create base payload, request and response data structures

This commit is contained in:
Valerio Ageno
2024-05-19 12:22:56 +02:00
parent d4c9b25b90
commit 208c18c94a
8 changed files with 102 additions and 24 deletions
+8 -9
View File
@@ -11,8 +11,9 @@ const AXUM_ENTRY_POINT: &'static str = r##"
// File automatically generated // File automatically generated
// Do not manually change it // Do not manually change it
use axum::extract::Request;
use axum::response::Html; use axum::response::Html;
use axum::{http::Uri, routing::get, Router}; use axum::{routing::get, Router};
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
use tuono_lib::{ssr, Ssr}; use tuono_lib::{ssr, Ssr};
@@ -31,15 +32,13 @@ async fn main() {
axum::serve(listener, app).await.unwrap(); axum::serve(listener, app).await.unwrap();
} }
async fn catch_all(uri: Uri) -> Html<String> { async fn catch_all(request: Request) -> Html<String> {
dbg!(&uri.path()); let pathname = &request.uri();
let path = &uri.path(); let headers = &request.headers();
let payload = format!( let req = tuono_lib::Request::new(pathname, headers);
r#"{{
"path": "{path}" 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))); let result = ssr::Js::SSR.with(|ssr| ssr.borrow_mut().render_to_string(Some(&payload)));
+4
View File
@@ -10,4 +10,8 @@ path = "src/lib.rs"
[dependencies] [dependencies]
ssr_rs = "0.5.1" ssr_rs = "0.5.1"
axum = "0.7.5"
tuono_lib_macros = { path = "../tuono_lib_macros"} tuono_lib_macros = { path = "../tuono_lib_macros"}
serde = { version = "1.0.202", features = ["derive"] }
serde_json = "1.0"
+8 -5
View File
@@ -1,8 +1,11 @@
mod payload;
mod request;
mod response;
pub mod ssr; pub mod ssr;
pub use payload::Payload;
pub use request::Request;
pub use response::Response;
pub use ssr_rs::Ssr; pub use ssr_rs::Ssr;
pub use tuono_lib_macros::handler; pub use tuono_lib_macros::handler;
pub enum Response {
Redirect(String),
Props(String),
}
+24
View File
@@ -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()
}
}
+38
View File
@@ -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<String, String>,
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: "",
}
}
}
+4
View File
@@ -0,0 +1,4 @@
pub enum Response {
Redirect(String),
Props(String),
}
+14 -8
View File
@@ -8,25 +8,31 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
let fn_name = item.clone().sig.ident; let fn_name = item.clone().sig.ident;
quote! { quote! {
use tuono_lib::Response;
use axum::response::Html; use axum::response::Html;
use axum::http::Uri;
use tuono_lib::ssr;
#item #item
pub async fn route(uri: Uri) -> Html<String> { pub async fn route(request: axum::extract::Request) -> Html<String> {
println!("Custom handler"); println!("Custom handler");
let props = #fn_name(); 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 { 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()) _ => Ok("500 Internal server error".to_string())
}; };
match res { match res {
Ok(html) => Html(html), Ok(html) => Html(html),
_ => Html("500".to_string()) _ => Html("500 internal server error".to_string())
} }
} }
@@ -44,7 +44,7 @@ interface RouterProviderProps {
} }
interface ServerProps { interface ServerProps {
path: string router: Location
} }
const initRouterStore = (props?: ServerProps): void => { const initRouterStore = (props?: ServerProps): void => {
@@ -52,7 +52,7 @@ const initRouterStore = (props?: ServerProps): void => {
if (typeof window === 'undefined') { if (typeof window === 'undefined') {
updateLocation({ updateLocation({
pathname: props?.path || '', pathname: props?.router.pathname || '',
hash: '', hash: '',
href: '', href: '',
searchStr: '', searchStr: '',