Skip to content

Commit

Permalink
fix: invalid values returned from params
Browse files Browse the repository at this point in the history
  • Loading branch information
elcharitas committed Dec 15, 2024
1 parent a7448ef commit e784bf6
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 20 deletions.
14 changes: 10 additions & 4 deletions crates/macros/src/core/param.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::Field;

pub(crate) fn param_macro(input: TokenStream) -> TokenStream {
let syn::ItemStruct {
Expand All @@ -10,16 +11,21 @@ pub(crate) fn param_macro(input: TokenStream) -> TokenStream {
} = syn::parse_macro_input!(input as syn::ItemStruct);

let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let field_names: Vec<_> = fields.iter().map(|field| field.ident.as_ref()).collect();
let fields: Vec<_> = fields
.iter()
.map(|Field { ident, .. }| {
quote! {
#ident: param.get(stringify!(#ident)).unwrap_or_default(),
}
})
.collect();

let expanded = quote! {
impl #impl_generics ngyn::shared::server::Transformer<'_> for #ident #ty_generics #where_clause {
fn transform(cx: &mut ngyn::prelude::NgynContext<'_>) -> Self {
let param = ngyn::shared::server::Param::transform(cx);
#ident {
#(
#field_names: param.get(stringify!(#field_names)).unwrap_or_default().parse().unwrap_or_default(),
)*
#(#fields)*
}
}
}
Expand Down
14 changes: 10 additions & 4 deletions crates/macros/src/core/query.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::Field;

pub(crate) fn query_macro(input: TokenStream) -> TokenStream {
let syn::ItemStruct {
Expand All @@ -10,16 +11,21 @@ pub(crate) fn query_macro(input: TokenStream) -> TokenStream {
} = syn::parse_macro_input!(input as syn::ItemStruct);

let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let field_names: Vec<_> = fields.iter().map(|field| field.ident.as_ref()).collect();
let fields: Vec<_> = fields
.iter()
.map(|Field { ident, .. }| {
quote! {
#ident: query.get(stringify!(#ident)).unwrap_or_default(),
}
})
.collect();

let expanded = quote! {
impl #impl_generics ngyn::shared::server::Transformer<'_> for #ident #ty_generics #where_clause {
fn transform(cx: &mut ngyn::prelude::NgynContext<'_>) -> Self {
let query = ngyn::shared::server::Query::transform(cx);
#ident {
#(
#field_names: query.get(stringify!(#field_names)).unwrap_or_default().parse().unwrap_or_default(),
)*
#(#fields)*
}
}
}
Expand Down
26 changes: 21 additions & 5 deletions crates/shared/src/core/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ use crate::{
Middleware, NgynMiddleware,
};

#[derive(Default)]
pub struct GroupRouter {
pub struct GroupRouter<'b> {
base_path: &'b str,
router: Router<RouteHandler>,
}

impl RouteInstance for GroupRouter {
impl RouteInstance for GroupRouter<'_> {
fn router_mut(&mut self) -> &mut Router<RouteHandler> {
&mut self.router
}

fn mount(&self) -> &str {
self.base_path
}
}

#[derive(Default)]
Expand Down Expand Up @@ -96,6 +100,12 @@ pub trait NgynPlatform: Default {

pub trait RouteInstance {
fn router_mut(&mut self) -> &mut Router<RouteHandler>;

/// Mounts the route on a path, defaults to "/"
fn mount(&self) -> &str {
"/"
}

/// Adds a route to the platform data.
///
/// ### Arguments
Expand All @@ -111,7 +121,7 @@ pub trait RouteInstance {
let route = if path.starts_with('/') {
method + path
} else {
method + "/" + path
method + self.mount() + path
};

self.router_mut().insert(route, handler).unwrap();
Expand Down Expand Up @@ -208,8 +218,14 @@ pub trait NgynEngine: NgynPlatform {
self.add_route(path, None, handler.into());
}

fn group(&mut self, registry: impl Fn(&mut GroupRouter)) -> Result<(), MergeError> {
/// Groups related routes
fn group(
&mut self,
base_path: &str,
registry: impl Fn(&mut GroupRouter),
) -> Result<(), MergeError> {
let mut group = GroupRouter {
base_path,
router: Router::<RouteHandler>::new(),
};
registry(&mut group);
Expand Down
16 changes: 10 additions & 6 deletions crates/shared/src/server/transformer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::borrow::Cow;
use std::{borrow::Cow, str::FromStr};

use bytes::Bytes;
use futures_util::StreamExt;
Expand Down Expand Up @@ -99,10 +99,12 @@ impl<'a> Param<'a> {
/// assert_eq!(param.get("name"), Some("John".to_string()));
/// assert_eq!(param.get("age"), None);
/// ```
pub fn get(&self, id: &str) -> Option<String> {
pub fn get<F: FromStr>(&self, id: &str) -> Option<F> {
for (key, value) in &self.data {
if *key == id {
return Some(value.to_string());
if let Ok(value) = value.parse() {
return Some(value);
}
}
}
None
Expand Down Expand Up @@ -131,7 +133,7 @@ impl<'a: 'b, 'b> Transformer<'a> for Param<'b> {
fn transform(cx: &'a mut NgynContext) -> Self {
let data: Vec<(&'a str, &'a str)> = cx
.params()
.unwrap_or_else(|| panic!("Extracting params should only be done in route handlers."))
.expect("Extracting params should only be done in route handlers.")
.iter()
.collect();
Param { data }
Expand Down Expand Up @@ -167,12 +169,14 @@ impl<'q> Query<'q> {
/// assert_eq!(query.get("name"), Some("John".to_string()));
/// assert_eq!(query.get("age"), None);
/// ```
pub fn get(&self, id: &str) -> Option<String> {
pub fn get<F: FromStr>(&self, id: &str) -> Option<F> {
let query = self.uri.query().unwrap_or("");
let query = url::form_urlencoded::parse(query.as_bytes());
for (key, value) in query {
if key == id {
return Some(value.to_string());
if let Ok(value) = value.parse() {
return Some(value);
}
}
}
None
Expand Down
2 changes: 1 addition & 1 deletion examples/weather_app/src/weather.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct WeatherGate;
impl NgynGate for WeatherGate {
async fn can_activate(cx: &mut NgynContext<'_>) -> bool {
let query = Query::transform(cx);
if query.get("location").is_some() {
if query.get::<String>("location").is_some() {
return true;
}
*cx.response().status_mut() = StatusCode::BAD_REQUEST;
Expand Down

0 comments on commit e784bf6

Please sign in to comment.