all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH] api macro: reuse generated default const for "unwrap_or"
@ 2020-10-26 17:29 Thomas Lamprecht
  2020-10-27  8:24 ` [pbs-devel] applied: " Wolfgang Bumiller
  0 siblings, 1 reply; 2+ messages in thread
From: Thomas Lamprecht @ 2020-10-26 17:29 UTC (permalink / raw)
  To: pbs-devel

Instead of setting a default value to a const and inside an
.unwrap_or_else closure, lets set it only to the const and reuse that
later in .unwrap_or

To achieve that we move the "unrwap_or" code for param plumbing code generation
a bit later so that we have easy access to the generated const name.
As all this code is related to optional/default-value stuff it does read still
relatively OK with that change, IMO.

This has the advantage of not getting a warning like:

>  warning: constant is never used: `API_METHOD_EXAMPLE_FOO_PARAM_DEFAULT_FORCE`
>   --> src/api2/node/foo.rs
>    |
> XY |             force: {
>    |             ^^^^^
>    = note: `#[warn(dead_code)]` on by default

When one has a API endpoint like:

> #[api(
>     input: {
>         properties: {
>             force: {
>                 type: bool,
>                 optional: true,
>                 default: false,
>             },
>         },
>     },
>     ...
> )]
> /// Example
> fn example_foo(force: bool) -> Result<(), Error> {
>     if force {
>         // do something
>     }
>     Ok(())
> }

It effectively changes the output for optional parameters with a default set
and no Option<T> from

> let p = p.unwrap_or_else(|| #default_value);

to

> let p = p.unwrap_or(#const_name_for_default);

where the "#const_name_for_default" is a pub const with value
"#default_value"

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---

So, I did not checked the surrounding stuff in depth, but it seemed relatively
clear what is happening here. So, while a good double check is surely good, and
soem implementation details may be discussed, it does not breaks tests (and I
negative checked that, to ensure there are tests for this) plus my use case
works too, the "constant is never used" warning goes away.

 proxmox-api-macro/src/api/method.rs | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/proxmox-api-macro/src/api/method.rs b/proxmox-api-macro/src/api/method.rs
index e94594f..1d32c60 100644
--- a/proxmox-api-macro/src/api/method.rs
+++ b/proxmox-api-macro/src/api/method.rs
@@ -414,18 +414,8 @@ fn create_wrapper_function(
                             #name_str,
                         ))?
                     });
-                } else if util::is_option_type(ty).is_none() {
-                    // Optional parameter without an Option<T> type requires a default:
-                    if let Some(def) = &default_value {
-                        body.extend(quote_spanned! { span =>
-                            .unwrap_or_else(|| #def)
-                        });
-                    } else {
-                        bail!(ty => "Optional parameter without Option<T> requires a default");
-                    }
                 }
-                body.extend(quote_spanned! { span => ; });
-                args.extend(quote_spanned! { span => #arg_name, });
+                let no_option_type = util::is_option_type(ty).is_none();
 
                 if let Some(def) = &default_value {
                     let name_uc = name.as_ident().to_string().to_uppercase();
@@ -438,7 +428,17 @@ fn create_wrapper_function(
                     default_consts.extend(quote_spanned! { span =>
                         pub const #name: #ty = #def;
                     });
+                    if optional && no_option_type {
+                        // Optional parameter without an Option<T> type requires a default:
+                        body.extend(quote_spanned! { span =>
+                            .unwrap_or(#name)
+                        });
+                    }
+                } else if optional && no_option_type {
+                    bail!(ty => "Optional parameter without Option<T> requires a default");
                 }
+                body.extend(quote_spanned! { span => ; });
+                args.extend(quote_spanned! { span => #arg_name, });
             }
         }
     }
-- 
2.27.0





^ permalink raw reply	[flat|nested] 2+ messages in thread

* [pbs-devel] applied: [PATCH] api macro: reuse generated default const for "unwrap_or"
  2020-10-26 17:29 [pbs-devel] [PATCH] api macro: reuse generated default const for "unwrap_or" Thomas Lamprecht
@ 2020-10-27  8:24 ` Wolfgang Bumiller
  0 siblings, 0 replies; 2+ messages in thread
From: Wolfgang Bumiller @ 2020-10-27  8:24 UTC (permalink / raw)
  To: Thomas Lamprecht; +Cc: pbs-devel

applied

On Mon, Oct 26, 2020 at 06:29:27PM +0100, Thomas Lamprecht wrote:
> Instead of setting a default value to a const and inside an
> .unwrap_or_else closure, lets set it only to the const and reuse that
> later in .unwrap_or
> 
> To achieve that we move the "unrwap_or" code for param plumbing code generation
> a bit later so that we have easy access to the generated const name.
> As all this code is related to optional/default-value stuff it does read still
> relatively OK with that change, IMO.
> 
> This has the advantage of not getting a warning like:
> 
> >  warning: constant is never used: `API_METHOD_EXAMPLE_FOO_PARAM_DEFAULT_FORCE`
> >   --> src/api2/node/foo.rs
> >    |
> > XY |             force: {
> >    |             ^^^^^
> >    = note: `#[warn(dead_code)]` on by default
> 
> When one has a API endpoint like:
> 
> > #[api(
> >     input: {
> >         properties: {
> >             force: {
> >                 type: bool,
> >                 optional: true,
> >                 default: false,
> >             },
> >         },
> >     },
> >     ...
> > )]
> > /// Example
> > fn example_foo(force: bool) -> Result<(), Error> {
> >     if force {
> >         // do something
> >     }
> >     Ok(())
> > }
> 
> It effectively changes the output for optional parameters with a default set
> and no Option<T> from
> 
> > let p = p.unwrap_or_else(|| #default_value);
> 
> to
> 
> > let p = p.unwrap_or(#const_name_for_default);
> 
> where the "#const_name_for_default" is a pub const with value
> "#default_value"
> 
> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
> ---
> 
> So, I did not checked the surrounding stuff in depth, but it seemed relatively
> clear what is happening here. So, while a good double check is surely good, and
> soem implementation details may be discussed, it does not breaks tests (and I
> negative checked that, to ensure there are tests for this) plus my use case
> works too, the "constant is never used" warning goes away.
> 
>  proxmox-api-macro/src/api/method.rs | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/proxmox-api-macro/src/api/method.rs b/proxmox-api-macro/src/api/method.rs
> index e94594f..1d32c60 100644
> --- a/proxmox-api-macro/src/api/method.rs
> +++ b/proxmox-api-macro/src/api/method.rs
> @@ -414,18 +414,8 @@ fn create_wrapper_function(
>                              #name_str,
>                          ))?
>                      });
> -                } else if util::is_option_type(ty).is_none() {
> -                    // Optional parameter without an Option<T> type requires a default:
> -                    if let Some(def) = &default_value {
> -                        body.extend(quote_spanned! { span =>
> -                            .unwrap_or_else(|| #def)
> -                        });
> -                    } else {
> -                        bail!(ty => "Optional parameter without Option<T> requires a default");
> -                    }
>                  }
> -                body.extend(quote_spanned! { span => ; });
> -                args.extend(quote_spanned! { span => #arg_name, });
> +                let no_option_type = util::is_option_type(ty).is_none();
>  
>                  if let Some(def) = &default_value {
>                      let name_uc = name.as_ident().to_string().to_uppercase();
> @@ -438,7 +428,17 @@ fn create_wrapper_function(
>                      default_consts.extend(quote_spanned! { span =>
>                          pub const #name: #ty = #def;
>                      });
> +                    if optional && no_option_type {
> +                        // Optional parameter without an Option<T> type requires a default:
> +                        body.extend(quote_spanned! { span =>
> +                            .unwrap_or(#name)
> +                        });
> +                    }
> +                } else if optional && no_option_type {
> +                    bail!(ty => "Optional parameter without Option<T> requires a default");
>                  }
> +                body.extend(quote_spanned! { span => ; });
> +                args.extend(quote_spanned! { span => #arg_name, });
>              }
>          }
>      }
> -- 
> 2.27.0




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-10-27  8:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-26 17:29 [pbs-devel] [PATCH] api macro: reuse generated default const for "unwrap_or" Thomas Lamprecht
2020-10-27  8:24 ` [pbs-devel] applied: " Wolfgang Bumiller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal