Skip to content

Commit

Permalink
Support default values for annotated server_fn arguments
Browse files Browse the repository at this point in the history
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 committed Sep 20, 2023
1 parent 1759a3e commit 39b0e93
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 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,30 @@ 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 39b0e93

Please sign in to comment.