Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add impl_from argument to #[server] proc_macro #2335

Merged
merged 6 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions leptos_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,11 @@ pub fn slot(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
/// - `"GetCbor"`: `GET` request with URL-encoded arguments and CBOR response
/// - `req` and `res` specify the HTTP request and response types to be used on the server (these
/// should usually only be necessary if you are integrating with a server other than Actix/Axum)
/// - `impl_from`: specifies whether to implement trait `From` for server function's type or not.
/// By default, if a server function only has one argument, the macro automatically implements the `From` trait
/// to convert from the argument type to the server function type, and vice versa, allowing you to convert
/// between them easily. Setting `impl_from` to `false` disables this, which can be necessary for argument types
/// for which this would create a conflicting implementation. (defaults to `true`)
///
/// ```rust,ignore
/// #[server(
Expand All @@ -891,6 +896,7 @@ pub fn slot(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
/// endpoint = "my_fn",
/// input = Cbor,
/// output = Json
/// impl_from = true
/// )]
/// pub async fn my_wacky_server_fn(input: Vec<String>) -> Result<usize, ServerFnError> {
/// todo!()
Expand Down
19 changes: 17 additions & 2 deletions server_fn_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub fn server_macro_impl(
res_ty,
client,
custom_wrapper,
impl_from,
} = args;
let prefix = prefix.unwrap_or_else(|| Literal::string(default_path));
let fn_path = fn_path.unwrap_or_else(|| Literal::string(""));
Expand Down Expand Up @@ -206,8 +207,11 @@ pub fn server_macro_impl(
FnArg::Receiver(_) => None,
FnArg::Typed(t) => Some((&t.pat, &t.ty)),
});
let from_impl =
(body.inputs.len() == 1 && first_field.is_some()).then(|| {
let impl_from = impl_from.map(|v| v.value).unwrap_or(true);
let from_impl = (body.inputs.len() == 1
&& first_field.is_some()
&& impl_from)
.then(|| {
let field = first_field.unwrap();
let (name, ty) = field;
quote! {
Expand Down Expand Up @@ -676,6 +680,7 @@ struct ServerFnArgs {
client: Option<Type>,
custom_wrapper: Option<Path>,
builtin_encoding: bool,
impl_from: Option<LitBool>,
}

impl Parse for ServerFnArgs {
Expand All @@ -693,6 +698,7 @@ impl Parse for ServerFnArgs {
let mut res_ty: Option<Type> = None;
let mut client: Option<Type> = None;
let mut custom_wrapper: Option<Path> = None;
let mut impl_from: Option<LitBool> = None;

let mut use_key_and_value = false;
let mut arg_pos = 0;
Expand Down Expand Up @@ -800,6 +806,14 @@ impl Parse for ServerFnArgs {
));
}
custom_wrapper = Some(stream.parse()?);
} else if key == "impl_from" {
if impl_from.is_some() {
return Err(syn::Error::new(
key.span(),
"keyword argument repeated: `impl_from`",
));
}
impl_from = Some(stream.parse()?);
} else {
return Err(lookahead.error());
}
Expand Down Expand Up @@ -895,6 +909,7 @@ impl Parse for ServerFnArgs {
res_ty,
client,
custom_wrapper,
impl_from,
})
}
}
Expand Down
Loading