-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
[Rust][REQ] Escape parameters instead of local variables #20337
Comments
thanks for the suggestion 👍 let's see if the community has feedback/question on this. cc @frol (2017/07) @farcaller (2017/08) @richardwhiuk (2019/07) @paladinzh (2020/05) @jacob-pro (2022/10) |
One option would be to take in openapi params as a struct. I've seen this pattern used around and it also solves the problem of naming the keys on the user side of using the generated code. Rust is smart enough to optimize those structs away, too, so it's not a performance hit (if you would ever care about that performance in face of the price of a networking call anyway). Do we expect users to look into generated code at all? because I could see some extreme corner case where having |
That is enabled by the openapi-generator/samples/client/petstore/rust/reqwest/petstore-async/src/apis/user_api.rs Lines 198 to 202 in e87c4ea
Agree to the performance impact, but its sometimes more convenient to just pass a single parameter in, rather than create a dummy struct, so I see why the config exists, to give users a choice.
Already thought about a |
@wing328 and I discussed the prefixes in local variables with generated Rust code. The following is a write-up trying to summarize our Ideas and discussion.
Is your feature request related to a problem? Please describe.
Current
rust
generated code, prepends all local variables with alocal_var_
prefix. The intention of this prefix is, to avoidname collisions
(See below a whole chapter on how they are possible right now).However, this has 3 downsides:
client
would cause problems.local_var_
prefix -> probably safe enough, no one will probably name their OpenApi Parameterlocal_var_client
local_var_31rsefw3eddfesrt234efae5zse6ftsera_
as a prefix -> if a user really useslocal_var_31rsefw3eddfesrt234efae5zse6ftsera_client
in their naming, they are crazyDescribe the solution you'd like
There exists a solution to it that solves 1) and 3) and greatly improves on 2) :
Instead of adding a prefix to the
local variable
we add a prefix to theparameter
.Why does adding a prefix to a parameter works, but not to a local variable?
OpenAPI parameters
are user input, they can be whatever the user wants.local variables
are defined in mustache files, they are not user-input, but are carefully chosen by OpenApiTools and changes need to be reviewed and merged.If we now escape the
local_variables
(e.g. by adding a prefix) we should slightly decrease the chance for a name collision).However, if we properly escape the user-input, e.g. by adding some prefix
p_
to theOpenAPI parameters
, AND we don't use the same prefix on our local variables, we can AVOID all such collisions. Because it is possible to add more characters for user-inputOpenAPI parameters
, but they cannot get rid of the prefixp_
(let aside they try to inject rust code in some sneaky way, we limit ourselves to valid names here).But changing parameter names disrupts the public interface
So before I opted to add a prefix to
OpenAPI parameters
in the generated code. ButOpenAPI parameters
are mapped to rust parameters, and we don't want to have an ugly function likebecause then this stuff is put in rust-generated docs and it is shown in the IDEs of people.
To mitigate this problem I would propose a mapping of parameters to prefixed_parameters at the beginning of the function:
Such a mapping is already used when
useSingleRequestParameter
is set. (see:openapi-generator/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache
Lines 86 to 89 in e87c4ea
Note: reusing an existing variable internally is not a problem, but a rust feature, even mentioned in the official book as "Shadowing"
https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
Note: there is a single limitation to local mapping, if the user creates an
OpenAPI parameter
and names itconfiguration
this cannot be mapped away. HOWEVER this is no new limitation, the limitation already exists in all today's variants. The status quo workaround here would be to use NameMapping or setuseSingleRequestParameter
. The workaround still would work with a parameter-prefix approach.Code example
You read enough, lets talk code:
We see: that the resulting rust code is easier to read. The mustache code too, because all those
p_
names are injected via variables anyway. The parameters stay unaffected and the resulting code is backward compatible on an interface level with the old code.There exists a mapping at the beginning of that function to put all parameters in a safe "namespace". Thus there can be no name conflicts afterwards. When using
useSingleRequestParameter
we can get rid of the mapping completely, as we could just use the value from its Grouped struct (e.g. See PoC: https://github.com/OpenAPITools/openapi-generator/pull/20203/files#diff-85ae3f26660bc69ea8d32481b66d705799993c1429e096f4be81c948bb1ab19dR59 )Describe alternatives you've considered
@wing328 and I discussed some alternatives on Slack, e.g.
configurable prefixes for local variables
( #20219 ) orno prefixes for local variables and no parameter unboxing in useSingleRequestParameter
( #20203 ). But they only shift the problem a bit rather than having a solid solutionAdditional context
Name Collisions
A name collision happens when a parameter is inserted in the function where a local variable exists.
E.g. look at
openapi-generator/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs
Lines 119 to 124 in e87c4ea
Imagine the user creates an OpenApi parameter called
configuration
. In that case, the generated rust could would NOT COMPILE because of a duplicate parameter error.Imagine the user creates an OpenApi parameter called
local_var_client
. As the Parameter is prob from a different type thanreqwest::Client
(it is probably a String/int/float/bool), this will NOT COMPILE because of a type error.Imagine the user creates an OpenApi parameter called
local_var_uri_str
and makes it aString
, the could would probably COMPILE, but we would have a logic error hard to detect.So we can conclude that we want to avoid Name collisions.
To avoid name-collisions in the past there were 3 options in openapi-generator:
local_var_
prefix already used right now, greatly reduces chance but is not perfect.useSingleRequestParameter
config (already works), and don't unpack them (works in theory, PoC [Rust] fix #20198, cleanup generated code #20203 )The text was updated successfully, but these errors were encountered: