Skip to content

Commit

Permalink
Fix: derive_from_request & increment version
Browse files Browse the repository at this point in the history
  • Loading branch information
kanarus committed Mar 5, 2024
1 parent 6a8fe09 commit c63e4c8
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 11 deletions.
3 changes: 2 additions & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ members = [
"realworld",
"quick_start",
"json_response",
"derive_from_request",
]

[workspace.dependencies]
# To assure "DEBUG" feature be off even if DEBUGing `../ohkami`,
# explicitly set `default-features = false`
ohkami = { version = "0.15.0", path = "../ohkami", default-features = false, features = ["rt_tokio", "utils", "testing"] }
ohkami = { version = "0.15.1", path = "../ohkami", default-features = false, features = ["rt_tokio", "utils", "testing"] }
tokio = { version = "1", features = ["full"] }
sqlx = { version = "0.7.3", features = ["runtime-tokio-native-tls", "postgres", "macros", "chrono", "uuid"] }
tracing = "0.1"
Expand Down
8 changes: 8 additions & 0 deletions examples/derive_from_request/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "derive_from_request"
version = "0.1.0"
edition = "2021"

[dependencies]
ohkami = { workspace = true }
tokio = { workspace = true }
54 changes: 54 additions & 0 deletions examples/derive_from_request/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#![allow(unused)]
fn main() {}

use ohkami::{FromRequest, Method};


struct RequestMethod(Method);
impl<'req> FromRequest<'req> for RequestMethod {
type Error = std::convert::Infallible;
fn from_request(req: &'req ohkami::prelude::Request) -> Result<Self, Self::Error> {
Ok(Self(req.method()))
}
}

struct RequestPath<'req>(std::borrow::Cow<'req, str>);
impl<'req> FromRequest<'req> for RequestPath<'req> {
type Error = std::convert::Infallible;
fn from_request(req: &'req ohkami::prelude::Request) -> Result<Self, Self::Error> {
Ok(Self(req.path()))
}
}

struct RequestPathOwned(String);
impl<'req> FromRequest<'req> for RequestPathOwned {
type Error = std::convert::Infallible;
fn from_request(req: &'req ohkami::prelude::Request) -> Result<Self, Self::Error> {
Ok(Self(req.path().into()))
}
}


#[derive(FromRequest)]
struct MethodAndPathA {
method: RequestMethod,
path: RequestPathOwned,
}

#[derive(FromRequest)]
struct MethodAndPathB<'req> {
method: RequestMethod,
path: RequestPath<'req>,
}

#[derive(FromRequest)]
struct MethodAndPathC(
RequestMethod,
RequestPathOwned,
);

#[derive(FromRequest)]
struct MethodAndPathD<'req>(
RequestMethod,
RequestPath<'req>,
);
2 changes: 1 addition & 1 deletion ohkami/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ohkami"
version = "0.15.0"
version = "0.15.1"
edition = "2021"
authors = ["kanarus <[email protected]>"]
description = "Build web app in intuitive and declarative code"
Expand Down
52 changes: 43 additions & 9 deletions ohkami_macros/src/from_request.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,53 @@
use proc_macro2::{Span, TokenStream};
use syn::{Error, ItemStruct, Result};
use syn::{Field, ItemStruct, Result};
use quote::quote;
use crate::components::from_request_lifetime;


pub(super) fn derive_from_request(target: TokenStream) -> Result<TokenStream> {
let s: ItemStruct = syn::parse2(target)?;

if s.generics.lifetimes().count() >= 2 {
return Err(Error::new(Span::call_site(), "`#[derive(FromRequest)]` doesn't support multiple lifetimes!"))
}
let name = &s.ident;

if s.semi_token.is_none() {/* struct S { 〜 } */

let generics_params_r = &s.generics.params;
let generics_params_l = &mut generics_params_r.clone();
let generics_where = &s.generics.where_clause;

} else {/* struct T(); */
let impl_lifetime = match s.generics.lifetimes().count() {
0 => {
let il = from_request_lifetime();
generics_params_l.push(il.clone());
il
}
1 => s.generics.params.first().unwrap().clone(),
_ => return Err(syn::Error::new(Span::call_site(), "#[derive(FromRequest)] doesn't support multiple lifetime params")),
};

}
let build = if s.semi_token.is_none() {/* struct S { 〜 } */
let fields = s.fields.into_iter()
.map(|Field { ident, ty, .. }| quote! {
#ident: <#ty as ::ohkami::FromRequest>::from_request(req)
.map_err(::ohkami::IntoResponse::into_response)?
});
quote![ Self { #( #fields ),* } ]

} else {/* struct T(); */
let fields = s.fields.into_iter()
.map(|Field { ty, .. }| quote! {
<#ty as ::ohkami::FromRequest>::from_request(req)
.map_err(::ohkami::IntoResponse::into_response)?
});
quote![ Self(#( #fields ),*) ]
};

todo!()
Ok(quote! {
impl<#generics_params_l> ::ohkami::FromRequest<#impl_lifetime> for #name<#generics_params_r>
#generics_where
{
type Error = ::ohkami::Response;
fn from_request(req: &#impl_lifetime ::ohkami::Request) -> ::std::result::Result<Self, Self::Error> {
::std::result::Result::Ok(#build)
}
}
})
}

0 comments on commit c63e4c8

Please sign in to comment.