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
// 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<String> {
dbg!(&uri.path());
let path = &uri.path();
async fn catch_all(request: Request) -> Html<String> {
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)));
+4
View File
@@ -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"
+8 -5
View File
@@ -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),
}
+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),
}
+13 -7
View File
@@ -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<String> {
pub async fn route(request: axum::extract::Request) -> Html<String> {
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 {
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())
}
}
@@ -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: '',