Skip to content

Commit cbfa7ee

Browse files
committed
Simplify consuming optional parameter values
Call .as_ref() for non-copyable types. This slightly simplifies some of the logic that determines when a borrow is required.
1 parent c6963b5 commit cbfa7ee

24 files changed

Lines changed: 561 additions & 560 deletions

File tree

packages/typespec-rust/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Other Changes
66

77
* Moved `TryFrom` impls for union types into their own file.
8+
* Call `.as_ref()` when consuming optional parameter values that are non-copyable types.
89

910
## 0.29.0 (2025-11-20)
1011

packages/typespec-rust/src/codegen/clients.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -762,14 +762,14 @@ function getMethodParamGroup(method: ClientMethod): MethodParamGroups {
762762
* @param indent the indentation helper currently in scope
763763
* @param param the parameter to which the contents of setter apply
764764
* @param setter the callback that emits the code to read from a param var
765-
* @param inClosure indicates if the value is being read from within a closure (e.g. pageable methods)
766765
* @returns
767766
*/
768-
function getParamValueHelper(indent: helpers.indentation, param: rust.MethodParameter, inClosure: boolean, setter: () => string): string {
767+
function getParamValueHelper(indent: helpers.indentation, param: rust.MethodParameter, setter: () => string): string {
769768
if (param.optional && param.type.kind !== 'literal') {
769+
const asRef = nonCopyableType(param.type) ? '.as_ref()' : '';
770770
// optional params are in the unwrapped options local var
771771
const op = indent.get() + helpers.buildIfBlock(indent, {
772-
condition: `let Some(${param.name}) = ${inClosure && nonCopyableType(param.type) ? '&' : ''}options.${param.name}`,
772+
condition: `let Some(${param.name}) = options.${param.name}${asRef}`,
773773
body: setter,
774774
});
775775
return op + '\n';
@@ -886,7 +886,7 @@ function constructUrl(indent: helpers.indentation, use: Use, method: ClientMetho
886886
}
887887

888888
if (pathParam.optional) {
889-
body += `${indent.get()}${pathVarName} = ${helpers.buildMatch(indent, `options.${pathParam.name}`, [{
889+
body += `${indent.get()}${pathVarName} = ${helpers.buildMatch(indent, `options.${pathParam.name}${nonCopyableType(pathParam.type) ? '.as_ref()' : ''}`, [{
890890
pattern: `Some(${pathParam.name})`,
891891
body: (indent) => wrapSortedVec(`${indent.get()}${pathVarName}.replace("{${pathParam.segment}}", ${paramExpression})\n`),
892892
}, {
@@ -925,15 +925,15 @@ function constructUrl(indent: helpers.indentation, use: Use, method: ClientMetho
925925

926926
for (const queryParam of paramGroups.query) {
927927
if (queryParam.kind === 'queryCollection' && queryParam.format === 'multi') {
928-
body += getParamValueHelper(indent, queryParam, false, () => {
928+
body += getParamValueHelper(indent, queryParam, () => {
929929
const valueVar = queryParam.name[0];
930930
let text = `${indent.get()}for ${valueVar} in ${queryParam.name}.iter() {\n`;
931931
text += `${indent.push().get()}${urlVarName}.query_pairs_mut().append_pair("${queryParam.key}", ${valueVar});\n`;
932932
text += `${indent.pop().get()}}\n`;
933933
return text;
934934
});
935935
} else if (queryParam.kind === 'queryHashMap') {
936-
body += getParamValueHelper(indent, queryParam, false, () => {
936+
body += getParamValueHelper(indent, queryParam, () => {
937937
let text = `${indent.get()}{\n`;
938938
text += `${indent.push().get()}let mut ${queryParam.name}_vec = ${queryParam.name}.iter().collect::<Vec<_>>();\n`;
939939
text += `${indent.get()}${queryParam.name}_vec.sort_by_key(|p| p.0);\n`;
@@ -948,7 +948,7 @@ function constructUrl(indent: helpers.indentation, use: Use, method: ClientMetho
948948
return text;
949949
});
950950
} else {
951-
body += getParamValueHelper(indent, queryParam, false, () => {
951+
body += getParamValueHelper(indent, queryParam, () => {
952952
return `${indent.get()}${urlVarName}.query_pairs_mut().append_pair("${queryParam.key}", ${getHeaderPathQueryParamValue(use, queryParam, !queryParam.optional, false)});\n`;
953953
});
954954
}
@@ -999,9 +999,9 @@ function applyHeaderParams(indent: helpers.indentation, use: Use, method: Client
999999
continue;
10001000
}
10011001

1002-
body += getParamValueHelper(indent, headerParam, inClosure, () => {
1002+
body += getParamValueHelper(indent, headerParam, () => {
10031003
if (headerParam.kind === 'headerHashMap') {
1004-
let setter = `for (k, v) in ${headerParam.type.kind === 'ref' ? '' : '&'}${headerParam.name} {\n`;
1004+
let setter = `for (k, v) in ${headerParam.name} {\n`;
10051005
setter += `${indent.push().get()}${requestVarName}.insert_header(format!("${headerParam.header}-{k}"), v);\n`;
10061006
setter += `${indent.pop().get()}}\n`;
10071007
return setter;
@@ -1051,7 +1051,7 @@ function constructRequest(indent: helpers.indentation, use: Use, method: ClientM
10511051

10521052
const bodyParam = paramGroups.body;
10531053
if (bodyParam) {
1054-
body += getParamValueHelper(indent, bodyParam, inClosure, () => {
1054+
body += getParamValueHelper(indent, bodyParam, () => {
10551055
let bodyParamContent = '';
10561056
if (optionalContentTypeParam) {
10571057
bodyParamContent = `${indent.get()}${requestVarName}.insert_header("${optionalContentTypeParam.header.toLowerCase()}", ${getHeaderPathQueryParamValue(use, optionalContentTypeParam, !inClosure, false)});\n`;
@@ -1296,7 +1296,7 @@ function getPageableMethodBody(indent: helpers.indentation, use: Use, client: ru
12961296
}
12971297
// add query params for reinjection
12981298
for (const reinjectedParam of reinjectedParams) {
1299-
content += getParamValueHelper(indent, reinjectedParam, true, () => {
1299+
content += getParamValueHelper(indent, reinjectedParam, () => {
13001300
return `${indent.get()}${nextLinkName}.query_pairs_mut().append_pair("${reinjectedParam.key}", ${getHeaderPathQueryParamValue(use, reinjectedParam, false, false)});\n`;
13011301
});
13021302
}
@@ -1734,8 +1734,8 @@ function getHeaderPathQueryParamValue(use: Use, param: HeaderParamType | PathPar
17341734
switch (paramType.kind) {
17351735
case 'String':
17361736
paramValue = paramName;
1737-
// if the param is on the client, or it's optional, then we must borrow
1738-
mustBorrow = (param.location === 'client' && fromSelf) || param.optional;
1737+
// if the param is on the client, then we must borrow
1738+
mustBorrow = param.location === 'client' && fromSelf;
17391739
break;
17401740
case 'str':
17411741
paramValue = paramName;

0 commit comments

Comments
 (0)