refactor: handle macros code in tuono_lib crate

This commit is contained in:
Valerio Ageno
2024-06-15 12:15:51 +02:00
parent 8b4db423b4
commit 70b4b9c28f
8 changed files with 63 additions and 41 deletions
+1 -1
View File
@@ -65,7 +65,7 @@ async fn catch_all(Path(params): Path<HashMap<String, String>>, request: Request
// TODO: remove unwrap
let payload = tuono_lib::Payload::new(&req, Box::new(""))
let payload = tuono_lib::Payload::new(&req, &"")
.client_payload()
.unwrap();
+1
View File
@@ -25,3 +25,4 @@ erased-serde = "0.4.5"
serde_json = "1.0"
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.1.2"}
+1 -1
View File
@@ -6,6 +6,6 @@ pub mod ssr;
pub use payload::Payload;
pub use request::Request;
pub use response::Response;
pub use response::{Props, Response};
pub use ssr_rs::Ssr;
pub use tuono_lib_macros::handler;
+2 -2
View File
@@ -8,11 +8,11 @@ use crate::Request;
/// This is the data shared to the client
pub struct Payload<'a> {
router: Location<'a>,
props: Box<dyn Serialize>,
props: &'a dyn Serialize,
}
impl<'a> Payload<'a> {
pub fn new(req: &Request<'a>, props: Box<dyn Serialize>) -> Payload<'a> {
pub fn new(req: &Request<'a>, props: &'a dyn Serialize) -> Payload<'a> {
Payload {
router: req.location(),
props,
+44 -1
View File
@@ -1,6 +1,49 @@
use crate::Request;
use crate::{ssr::Js, Payload};
use axum::http::StatusCode;
use axum::response::{Html, IntoResponse};
use axum::Json;
use erased_serde::Serialize;
pub struct Props {
data: Box<dyn Serialize>,
http_code: StatusCode,
}
pub enum Response {
Redirect(String),
Props(Box<dyn Serialize>),
Props(Props),
}
impl Props {
pub fn new(data: impl Serialize + 'static) -> Self {
Props {
data: Box::new(data),
http_code: StatusCode::OK,
}
}
}
impl Response {
pub fn render_to_string(&self, req: Request) -> impl IntoResponse {
match self {
Self::Props(Props { data, http_code: _ }) => {
let payload = Payload::new(&req, data).client_payload().unwrap();
match Js::SSR.with(|ssr| ssr.borrow_mut().render_to_string(Some(&payload))) {
Ok(html) => Html(html),
Err(_) => Html("500 Internal server error".to_string()),
}
}
// TODO: Handle here other enum arms
_ => todo!(),
}
}
pub fn json(&self) -> impl IntoResponse {
match self {
Self::Props(Props { data, http_code: _ }) => Json(data).into_response(),
_ => axum::Json("").into_response(),
}
}
}
+8 -30
View File
@@ -16,51 +16,29 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
#item
pub async fn route(
Path(params): Path<HashMap<String, String>>,
State(client): State<Client>,
Path(params): Path<HashMap<String, String>>,
State(client): State<Client>,
request: axum::extract::Request
) -> Html<String> {
) -> impl IntoResponse {
let pathname = &request.uri();
let headers = &request.headers();
let req = tuono_lib::Request::new(pathname, headers, params);
let local_response = #fn_name(req.clone(), client).await;
let res = match local_response {
tuono_lib::Response::Props(val) => {
// TODO: remove unwrap
let payload = tuono_lib::Payload::new(&req, val).client_payload().unwrap();
tuono_lib::ssr::Js::SSR.with(|ssr| ssr.borrow_mut().render_to_string(Some(&payload)))
},
/// TODO: handle here redirection and rewrite
_ => Ok("500 Internal server error".to_string())
};
match res {
Ok(html) => Html(html),
_ => Html("500 internal server error".to_string())
}
#fn_name(req.clone(), client).await.render_to_string(req)
}
pub async fn api(
Path(params): Path<HashMap<String, String>>,
State(client): State<Client>,
Path(params): Path<HashMap<String, String>>,
State(client): State<Client>,
request: axum::extract::Request
) -> axum::response::Response {
) -> impl IntoResponse{
let pathname = &request.uri();
let headers = &request.headers();
let req = tuono_lib::Request::new(pathname, headers, params);
let local_response = #fn_name(req.clone(), client).await;
let res = match local_response{
tuono_lib::Response::Props(val) => return axum::Json(val).into_response(),
_ => return axum::Json("").into_response()
};
#fn_name(req.clone(), client).await.json()
}
}
.into()
+3 -3
View File
@@ -1,6 +1,6 @@
// src/routes/index.rs
use serde::{Deserialize, Serialize};
use tuono_lib::{Request, Response};
use tuono_lib::{Props, Request, Response};
const ALL_POKEMON: &str = "https://pokeapi.co/api/v2/pokemon?limit=151";
@@ -20,8 +20,8 @@ async fn get_all_pokemons(_req: Request<'_>, fetch: reqwest::Client) -> Response
return match fetch.get(ALL_POKEMON).send().await {
Ok(res) => {
let data = res.json::<Pokemons>().await.unwrap();
Response::Props(Box::new(data))
Response::Props(Props::new(data))
}
Err(_err) => Response::Props(Box::new(Pokemons { results: vec![] })),
Err(_err) => Response::Props(Props::new(Pokemons { results: vec![] })),
};
}
@@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize};
use tuono_lib::{Request, Response};
use tuono_lib::{Props, Request, Response};
const POKEMON_API: &str = "https://pokeapi.co/api/v2/pokemon";
@@ -19,9 +19,9 @@ async fn get_pokemon(req: Request<'_>, fetch: reqwest::Client) -> Response {
return match fetch.get(format!("{POKEMON_API}/{pokemon}")).send().await {
Ok(res) => {
let data = res.json::<Pokemon>().await.unwrap();
Response::Props(Box::new(data))
Response::Props(Props::new(data))
}
Err(_err) => Response::Props(Box::new(Pokemon {
Err(_err) => Response::Props(Props::new(Pokemon {
name: "Nope".to_string(),
id: 0,
weight: 0,