Skip to content

Commit

Permalink
feat: support default values for annotated server_fn arguments with `…
Browse files Browse the repository at this point in the history
…#[server(default)]` (#1762)

This allows form submission with checkbox inputs to work.
For example:

    let doit = create_server_action::<DoItSFn>();
    <ActionForm action=doit>
      <input type="checkbox" name="is_good" value="true"/>
      <input type="submit"/>
    </ActionForm>

    #[server(DoItSFn, "/api")]
    pub async fn doit(#[server(default)] is_good: bool) -> Result<(), ServerFnError> {}

If is_good is absent in the request to the server API,
`Default::default()` is used instead.
  • Loading branch information
g2p authored Sep 21, 2023
1 parent f2117b1 commit 2c8f464
Showing 1 changed file with 29 additions and 4 deletions.
33 changes: 29 additions & 4 deletions server_fn_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ pub fn server_macro_impl(
let fn_path = fn_path.unwrap_or_else(|| Literal::string(""));
let encoding = quote!(#server_fn_path::#encoding);

let body = syn::parse::<ServerFnBody>(body.into())?;
let mut body = syn::parse::<ServerFnBody>(body.into())?;
let fn_name = &body.ident;
let fn_name_as_str = body.ident.to_string();
let vis = body.vis;
let block = body.block;

let fields = body
.inputs
.iter()
.iter_mut()
.filter(|f| {
if let Some(ctx) = &server_context {
!fn_arg_is_cx(f, ctx)
Expand All @@ -110,8 +110,33 @@ pub fn server_macro_impl(
}
FnArg::Typed(t) => t,
};
quote! { pub #typed_arg }
});
let mut default = false;
let mut other_attrs = Vec::new();
for attr in typed_arg.attrs.iter() {
if !attr.path().is_ident("server") {
other_attrs.push(attr.clone());
continue;
}
attr.parse_nested_meta(|meta| {
if meta.path.is_ident("default") && meta.input.is_empty() {
default = true;
Ok(())
} else {
Err(meta.error(
"Unrecognized #[server] attribute, expected \
#[server(default)]",
))
}
})?;
}
typed_arg.attrs = other_attrs;
if default {
Ok(quote! { #[serde(default)] pub #typed_arg })
} else {
Ok(quote! { pub #typed_arg })
}
})
.collect::<Result<Vec<_>>>()?;

let cx_arg = body.inputs.iter().next().and_then(|f| {
server_context
Expand Down

0 comments on commit 2c8f464

Please sign in to comment.