@azure-tools/typespec-rust 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/codegen/clients.d.ts.map +1 -1
- package/dist/src/codegen/clients.js +205 -120
- package/dist/src/codegen/clients.js.map +1 -1
- package/dist/src/codegen/context.d.ts.map +1 -1
- package/dist/src/codegen/context.js +3 -1
- package/dist/src/codegen/context.js.map +1 -1
- package/dist/src/codegen/enums.d.ts +2 -2
- package/dist/src/codegen/enums.js +57 -22
- package/dist/src/codegen/enums.js.map +1 -1
- package/dist/src/codegen/helpers.d.ts +10 -0
- package/dist/src/codegen/helpers.d.ts.map +1 -1
- package/dist/src/codegen/helpers.js +29 -3
- package/dist/src/codegen/helpers.js.map +1 -1
- package/dist/src/codegen/lib.js +1 -1
- package/dist/src/codegen/lib.js.map +1 -1
- package/dist/src/codegen/models.js +12 -6
- package/dist/src/codegen/models.js.map +1 -1
- package/dist/src/codemodel/client.d.ts +10 -8
- package/dist/src/codemodel/client.d.ts.map +1 -1
- package/dist/src/codemodel/client.js +1 -0
- package/dist/src/codemodel/client.js.map +1 -1
- package/dist/src/codemodel/crate.d.ts.map +1 -1
- package/dist/src/codemodel/crate.js +5 -2
- package/dist/src/codemodel/crate.js.map +1 -1
- package/dist/src/codemodel/types.d.ts +2 -11
- package/dist/src/codemodel/types.d.ts.map +1 -1
- package/dist/src/codemodel/types.js +0 -7
- package/dist/src/codemodel/types.js.map +1 -1
- package/dist/src/shared/shared.d.ts.map +1 -1
- package/dist/src/shared/shared.js +4 -1
- package/dist/src/shared/shared.js.map +1 -1
- package/dist/src/tcgcadapter/adapter.d.ts +9 -1
- package/dist/src/tcgcadapter/adapter.d.ts.map +1 -1
- package/dist/src/tcgcadapter/adapter.js +117 -72
- package/dist/src/tcgcadapter/adapter.js.map +1 -1
- package/package.json +17 -17
|
@@ -201,13 +201,20 @@ export function emitClients(crate) {
|
|
|
201
201
|
if (method.kind !== 'clientaccessor' && method.responseHeaders) {
|
|
202
202
|
body += getHeaderTraitDocComment(indent, crate, method);
|
|
203
203
|
}
|
|
204
|
+
const paramsInfo = getMethodParamsCountAndSig(method, use);
|
|
205
|
+
if (paramsInfo.count > 7) {
|
|
206
|
+
// clippy will by default warn on 7+ args in a method.
|
|
207
|
+
// note that this doesn't include self which is included
|
|
208
|
+
// in the count.
|
|
209
|
+
body += `${indent.get()}#[allow(clippy::too_many_arguments)]\n`;
|
|
210
|
+
}
|
|
204
211
|
if (isPublicApi) {
|
|
205
212
|
body += `${indent.get()}#[tracing::function("${method.languageIndependentName}")]\n`;
|
|
206
213
|
}
|
|
207
214
|
else if (isSubclientNew) {
|
|
208
215
|
body += `${indent.get()}#[tracing::subclient]\n`;
|
|
209
216
|
}
|
|
210
|
-
body += `${indent.get()}${helpers.emitVisibility(method.visibility)}${async}fn ${method.name}(${
|
|
217
|
+
body += `${indent.get()}${helpers.emitVisibility(method.visibility)}${async}fn ${method.name}(${paramsInfo.sig}) -> ${returnType} {\n`;
|
|
211
218
|
body += `${indent.push().get()}${methodBody(indent)}\n`;
|
|
212
219
|
body += `${indent.pop().get()}}\n`; // end method
|
|
213
220
|
if (i + 1 < client.methods.length) {
|
|
@@ -381,21 +388,24 @@ function getConstructorParamsSig(params, options, use) {
|
|
|
381
388
|
}
|
|
382
389
|
/**
|
|
383
390
|
* creates the parameter signature for a client method
|
|
384
|
-
* e.g. "foo: i32, bar: String, options: MethodOptions"
|
|
391
|
+
* e.g. "foo: i32, bar: String, options: MethodOptions".
|
|
392
|
+
* also returns the number of parameters in the sig.
|
|
385
393
|
*
|
|
386
394
|
* @param method the Rust method for which to create the param sig
|
|
387
395
|
* @param use the use statement builder currently in scope
|
|
388
|
-
* @returns the method params sig
|
|
396
|
+
* @returns the method params count and sig
|
|
389
397
|
*/
|
|
390
|
-
function
|
|
398
|
+
function getMethodParamsCountAndSig(method, use) {
|
|
391
399
|
const paramsSig = new Array();
|
|
392
400
|
paramsSig.push(formatParamTypeName(method.self));
|
|
401
|
+
let count = 1; // self
|
|
393
402
|
if (method.kind === 'clientaccessor') {
|
|
394
403
|
// client accessor params don't have a concept
|
|
395
404
|
// of optionality nor do they contain literals
|
|
396
405
|
for (const param of method.params) {
|
|
397
406
|
use.addForType(param.type);
|
|
398
407
|
paramsSig.push(`${param.name}: ${formatParamTypeName(param)}`);
|
|
408
|
+
++count;
|
|
399
409
|
}
|
|
400
410
|
}
|
|
401
411
|
else {
|
|
@@ -414,11 +424,13 @@ function getMethodParamsSig(method, use) {
|
|
|
414
424
|
if (param.location === 'method' && !param.optional) {
|
|
415
425
|
use.addForType(param.type);
|
|
416
426
|
paramsSig.push(`${param.name}: ${formatParamTypeName(param)}`);
|
|
427
|
+
++count;
|
|
417
428
|
}
|
|
418
429
|
}
|
|
419
430
|
paramsSig.push(`options: ${helpers.getTypeDeclaration(method.options, 'anonymous')}`);
|
|
431
|
+
++count;
|
|
420
432
|
}
|
|
421
|
-
return paramsSig.join(', ');
|
|
433
|
+
return { count: count, sig: paramsSig.join(', ') };
|
|
422
434
|
}
|
|
423
435
|
/**
|
|
424
436
|
* returns documentation for header trait access if the method has response headers.
|
|
@@ -436,7 +448,18 @@ function getHeaderTraitDocComment(indent, crate, method) {
|
|
|
436
448
|
let headerDocs = `${indent.get()}///\n`;
|
|
437
449
|
headerDocs += `${indent.get()}/// ## Response Headers\n`;
|
|
438
450
|
headerDocs += `${indent.get()}///\n`;
|
|
439
|
-
|
|
451
|
+
let returnType;
|
|
452
|
+
switch (method.returns.type.kind) {
|
|
453
|
+
case 'asyncResponse':
|
|
454
|
+
case 'response':
|
|
455
|
+
returnType = method.returns.type.name;
|
|
456
|
+
break;
|
|
457
|
+
default:
|
|
458
|
+
// for pagers/pollers we want their generic type argument type name
|
|
459
|
+
returnType = method.returns.type.type.name;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
headerDocs += `${indent.get()}/// The returned [${helpers.wrapInBackTicks(returnType)}](azure_core::http::${returnType}) implements the [${helpers.wrapInBackTicks(traitName)}] trait, which provides\n`;
|
|
440
463
|
headerDocs += `${indent.get()}/// access to response headers. For example:\n`;
|
|
441
464
|
headerDocs += `${indent.get()}///\n`;
|
|
442
465
|
headerDocs += emitHeaderTraitDocExample(crate.name, method.responseHeaders, indent);
|
|
@@ -634,7 +657,7 @@ function getParamValueHelper(indent, param, inClosure, setter) {
|
|
|
634
657
|
if (param.optional && param.type.kind !== 'literal') {
|
|
635
658
|
// optional params are in the unwrapped options local var
|
|
636
659
|
const op = indent.get() + helpers.buildIfBlock(indent, {
|
|
637
|
-
condition: `let Some(${param.name}) = ${inClosure ? '&' : ''}options.${param.name}`,
|
|
660
|
+
condition: `let Some(${param.name}) = ${inClosure && nonCopyableType(param.type) ? '&' : ''}options.${param.name}`,
|
|
638
661
|
body: setter,
|
|
639
662
|
});
|
|
640
663
|
return op + '\n';
|
|
@@ -648,45 +671,37 @@ function getParamValueHelper(indent, param, inClosure, setter) {
|
|
|
648
671
|
* @param use the use statement builder currently in scope
|
|
649
672
|
* @param method the method for which we're building the body
|
|
650
673
|
* @param paramGroups the param groups for the provided method
|
|
651
|
-
* @param urlVarName the name of the var that contains the azure_core::Url
|
|
674
|
+
* @param urlVarName the name of the var that contains the azure_core::Url
|
|
652
675
|
* @returns the URL construction code
|
|
653
676
|
*/
|
|
654
|
-
function constructUrl(indent, use, method, paramGroups, urlVarName
|
|
677
|
+
function constructUrl(indent, use, method, paramGroups, urlVarName) {
|
|
655
678
|
// for paths that contain query parameters, we must set the query params separately.
|
|
656
679
|
// including them in the call to set_path() causes the chars to be path-escaped.
|
|
657
680
|
const pathChunks = method.httpPath.split('?');
|
|
658
681
|
if (pathChunks.length > 2) {
|
|
659
682
|
throw new CodegenError('InternalError', 'too many HTTP path chunks');
|
|
660
683
|
}
|
|
661
|
-
/** returns & if the param needs to be borrowed (which is the majority of cases), else the empty string */
|
|
662
|
-
const borrowOrNot = function (param) {
|
|
663
|
-
// for string-based enums we call .as_ref() which elides the need to borrow.
|
|
664
|
-
// for numeric-based enums the borrow will be necessary.
|
|
665
|
-
// TODO: https://github.com/Azure/typespec-rust/issues/25
|
|
666
|
-
if (param.type.kind !== 'enum' && (param.type.kind !== 'ref' || param.type.type.kind === 'encodedBytes' || param.type.type.kind === 'slice')) {
|
|
667
|
-
return '&';
|
|
668
|
-
}
|
|
669
|
-
return '';
|
|
670
|
-
};
|
|
671
684
|
let body = '';
|
|
672
685
|
// if path is just "/" no need to set it again, we're already there
|
|
673
686
|
if (pathChunks[0] !== '/') {
|
|
687
|
+
use.add('azure_core::http', 'UrlExt');
|
|
674
688
|
let path = `"${pathChunks[0]}"`;
|
|
675
689
|
if (paramGroups.path.length === 0) {
|
|
676
690
|
// no path params, just a static path
|
|
677
|
-
body += `${indent.get()}${urlVarName}
|
|
691
|
+
body += `${indent.get()}${urlVarName}.append_path(${path});\n`;
|
|
678
692
|
}
|
|
679
693
|
else if (paramGroups.path.length === 1 && pathChunks[0] === `{${paramGroups.path[0].segment}}`) {
|
|
680
694
|
// for a single path param (i.e. "{foo}") we can directly join the path param's value
|
|
681
695
|
const pathParam = paramGroups.path[0];
|
|
682
|
-
body += `${indent.get()}${urlVarName}
|
|
696
|
+
body += `${indent.get()}${urlVarName}.append_path(${getHeaderPathQueryParamValue(use, pathParam, true, false)});\n`;
|
|
683
697
|
}
|
|
684
698
|
else {
|
|
685
699
|
// we have path params that need to have their segments replaced with the param values
|
|
686
|
-
|
|
700
|
+
const pathVarName = helpers.getUniqueVarName(method.params, ['path', 'path_var']);
|
|
701
|
+
body += `${indent.get()}let mut ${pathVarName} = String::from(${path});\n`;
|
|
687
702
|
for (const pathParam of paramGroups.path) {
|
|
688
703
|
let wrapSortedVec = (s) => s;
|
|
689
|
-
let paramExpression
|
|
704
|
+
let paramExpression;
|
|
690
705
|
if (pathParam.kind === 'pathHashMap') {
|
|
691
706
|
wrapSortedVec = (s) => `${indent.get()}{`
|
|
692
707
|
+ `${indent.push().get()}let mut ${pathParam.name}_vec = ${pathParam.name}.iter().collect::<Vec<_>>();\n`
|
|
@@ -737,6 +752,8 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
737
752
|
}
|
|
738
753
|
}
|
|
739
754
|
else {
|
|
755
|
+
// skip borrowing by default as we borrow from format!()
|
|
756
|
+
paramExpression = getHeaderPathQueryParamValue(use, pathParam, true, true);
|
|
740
757
|
switch (pathParam.style) {
|
|
741
758
|
case 'path':
|
|
742
759
|
paramExpression = `&format!("/{${paramExpression}}")`;
|
|
@@ -748,24 +765,25 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
748
765
|
paramExpression = `&format!(";${pathParam.name}={${paramExpression}}")`;
|
|
749
766
|
break;
|
|
750
767
|
default:
|
|
751
|
-
|
|
768
|
+
// use default borrowing calculation logic
|
|
769
|
+
paramExpression = getHeaderPathQueryParamValue(use, pathParam, true, false);
|
|
752
770
|
}
|
|
753
771
|
}
|
|
754
772
|
if (pathParam.optional) {
|
|
755
|
-
body += `${indent.get()}
|
|
773
|
+
body += `${indent.get()}${pathVarName} = ${helpers.buildMatch(indent, `options.${pathParam.name}`, [{
|
|
756
774
|
pattern: `Some(${pathParam.name})`,
|
|
757
|
-
body: (indent) => wrapSortedVec(`${indent.get()}
|
|
775
|
+
body: (indent) => wrapSortedVec(`${indent.get()}${pathVarName}.replace("{${pathParam.segment}}", ${paramExpression})\n`),
|
|
758
776
|
}, {
|
|
759
777
|
pattern: `None`,
|
|
760
|
-
body: (indent) => `${indent.get()}
|
|
778
|
+
body: (indent) => `${indent.get()}${pathVarName}.replace("{${pathParam.segment}}", "")\n`,
|
|
761
779
|
}])};\n`;
|
|
762
780
|
}
|
|
763
781
|
else {
|
|
764
|
-
body += wrapSortedVec(`${indent.get()}
|
|
782
|
+
body += wrapSortedVec(`${indent.get()}${pathVarName} = ${pathVarName}.replace("{${pathParam.segment}}", ${paramExpression});\n`);
|
|
765
783
|
}
|
|
766
784
|
}
|
|
767
|
-
path =
|
|
768
|
-
body += `${indent.get()}${urlVarName}
|
|
785
|
+
path = `&${pathVarName}`;
|
|
786
|
+
body += `${indent.get()}${urlVarName}.append_path(${path});\n`;
|
|
769
787
|
}
|
|
770
788
|
}
|
|
771
789
|
if (pathChunks.length === 2) {
|
|
@@ -819,9 +837,7 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
819
837
|
}
|
|
820
838
|
else {
|
|
821
839
|
body += getParamValueHelper(indent, queryParam, false, () => {
|
|
822
|
-
|
|
823
|
-
const borrow = queryParam.type.kind === 'enum' ? '' : borrowOrNot(queryParam);
|
|
824
|
-
return `${indent.get()}${urlVarName}.query_pairs_mut().append_pair("${queryParam.key}", ${borrow}${getHeaderPathQueryParamValue(use, queryParam, !queryParam.optional)});\n`;
|
|
840
|
+
return `${indent.get()}${urlVarName}.query_pairs_mut().append_pair("${queryParam.key}", ${getHeaderPathQueryParamValue(use, queryParam, !queryParam.optional, false)});\n`;
|
|
825
841
|
});
|
|
826
842
|
}
|
|
827
843
|
}
|
|
@@ -837,7 +853,7 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
837
853
|
* @param inClosure indicates if the request is being constructed within a closure (e.g. pageable methods)
|
|
838
854
|
* @returns the code which sets HTTP headers for the request
|
|
839
855
|
*/
|
|
840
|
-
function applyHeaderParams(indent, use, method, paramGroups, inClosure) {
|
|
856
|
+
function applyHeaderParams(indent, use, method, paramGroups, inClosure, requestVarName) {
|
|
841
857
|
var _a, _b, _c;
|
|
842
858
|
let body = '';
|
|
843
859
|
for (const headerParam of paramGroups.header) {
|
|
@@ -857,7 +873,7 @@ function applyHeaderParams(indent, use, method, paramGroups, inClosure) {
|
|
|
857
873
|
]) + ';\n';
|
|
858
874
|
body += indent.get() + helpers.buildIfBlock(indent, {
|
|
859
875
|
condition: `let Some(${headerParam.name}) = ${headerParam.name}`,
|
|
860
|
-
body: (indent) => `${indent.get()}
|
|
876
|
+
body: (indent) => `${indent.get()}${requestVarName}.insert_header("${headerParam.header}", ${headerParam.name});\n`,
|
|
861
877
|
}) + '\n';
|
|
862
878
|
continue;
|
|
863
879
|
}
|
|
@@ -869,15 +885,12 @@ function applyHeaderParams(indent, use, method, paramGroups, inClosure) {
|
|
|
869
885
|
}
|
|
870
886
|
body += getParamValueHelper(indent, headerParam, inClosure, () => {
|
|
871
887
|
if (headerParam.kind === 'headerHashMap') {
|
|
872
|
-
let setter = `for (k, v) in
|
|
873
|
-
setter += `${indent.push().get()}
|
|
888
|
+
let setter = `for (k, v) in ${headerParam.type.kind === 'ref' ? '' : '&'}${headerParam.name} {\n`;
|
|
889
|
+
setter += `${indent.push().get()}${requestVarName}.insert_header(format!("${headerParam.header}-{k}"), v);\n`;
|
|
874
890
|
setter += `${indent.pop().get()}}\n`;
|
|
875
891
|
return setter;
|
|
876
892
|
}
|
|
877
|
-
|
|
878
|
-
// client or we're in a closure and the param is required (header params are always owned)
|
|
879
|
-
const borrow = nonCopyableType(headerParam.type) && (headerParam.location === 'client' || (inClosure && !headerParam.optional)) ? '&' : '';
|
|
880
|
-
return `${indent.get()}request.insert_header("${headerParam.header.toLowerCase()}", ${borrow}${getHeaderPathQueryParamValue(use, headerParam, !inClosure)});\n`;
|
|
893
|
+
return `${indent.get()}${requestVarName}.insert_header("${headerParam.header.toLowerCase()}", ${getHeaderPathQueryParamValue(use, headerParam, !inClosure, false)});\n`;
|
|
881
894
|
});
|
|
882
895
|
}
|
|
883
896
|
return body;
|
|
@@ -896,13 +909,17 @@ function isOptionalContentTypeHeader(headerParam) {
|
|
|
896
909
|
* @param method the method for which we're building the body
|
|
897
910
|
* @param paramGroups the param groups for the provided method
|
|
898
911
|
* @param inClosure indicates if the request is being constructed within a closure (e.g. pageable methods)
|
|
912
|
+
* @param urlVarName the name of var that contains the URL
|
|
899
913
|
* @param cloneUrl indicates if url should be cloned when it is passed to initialize request
|
|
900
914
|
* @param forceMut indicates whether request should get declared as 'mut' regardless of whether there are any headers to set
|
|
901
915
|
* @returns the request construction code
|
|
902
916
|
*/
|
|
903
|
-
function constructRequest(indent, use, method, paramGroups, inClosure, cloneUrl = false, forceMut = true) {
|
|
904
|
-
|
|
905
|
-
|
|
917
|
+
function constructRequest(indent, use, method, paramGroups, inClosure, urlVarName, cloneUrl = false, forceMut = true) {
|
|
918
|
+
// when constructing the request var name we need to ensure
|
|
919
|
+
// that it doesn't collide with any parameter name.
|
|
920
|
+
const requestVarName = helpers.getUniqueVarName(method.params, ['request', 'core_req']);
|
|
921
|
+
let body = `${indent.get()}let ${(forceMut || paramGroups.header.length > 0) ? 'mut ' : ''}${requestVarName} = Request::new(${urlVarName}${cloneUrl ? '.clone()' : ''}, Method::${codegen.capitalize(method.httpMethod)});\n`;
|
|
922
|
+
body += applyHeaderParams(indent, use, method, paramGroups, inClosure, requestVarName);
|
|
906
923
|
let optionalContentTypeParam;
|
|
907
924
|
for (const headerParam of paramGroups.header) {
|
|
908
925
|
// if the content-type header is optional, we need to emit it inside the "if let Some(body)" clause below.
|
|
@@ -915,9 +932,9 @@ function constructRequest(indent, use, method, paramGroups, inClosure, cloneUrl
|
|
|
915
932
|
body += getParamValueHelper(indent, bodyParam, inClosure, () => {
|
|
916
933
|
let bodyParamContent = '';
|
|
917
934
|
if (optionalContentTypeParam) {
|
|
918
|
-
bodyParamContent = `${indent.get()}
|
|
935
|
+
bodyParamContent = `${indent.get()}${requestVarName}.insert_header("${optionalContentTypeParam.header.toLowerCase()}", ${getHeaderPathQueryParamValue(use, optionalContentTypeParam, !inClosure, false)});\n`;
|
|
919
936
|
}
|
|
920
|
-
bodyParamContent += `${indent.get()}
|
|
937
|
+
bodyParamContent += `${indent.get()}${requestVarName}.set_body(${bodyParam.name}${inClosure ? '.clone()' : ''});\n`;
|
|
921
938
|
return bodyParamContent;
|
|
922
939
|
});
|
|
923
940
|
}
|
|
@@ -947,9 +964,12 @@ function constructRequest(indent, use, method, paramGroups, inClosure, cloneUrl
|
|
|
947
964
|
body += `${indent.get()}${initializer},\n`;
|
|
948
965
|
}
|
|
949
966
|
body += `${indent.pop().get()}}.try_into()?;\n`;
|
|
950
|
-
body += `${indent.get()}
|
|
967
|
+
body += `${indent.get()}${requestVarName}.set_body(body);\n`;
|
|
951
968
|
}
|
|
952
|
-
return
|
|
969
|
+
return {
|
|
970
|
+
requestVarName: requestVarName,
|
|
971
|
+
content: body
|
|
972
|
+
};
|
|
953
973
|
}
|
|
954
974
|
/**
|
|
955
975
|
* Returns 'mut ' if the Url local var needs to be mutable, else the empty string.
|
|
@@ -1026,13 +1046,15 @@ function emitEmptyPathParamCheck(indent, param) {
|
|
|
1026
1046
|
*/
|
|
1027
1047
|
function getAsyncMethodBody(indent, use, client, method) {
|
|
1028
1048
|
use.add('azure_core::http', 'Method', 'Request');
|
|
1049
|
+
const urlVarName = helpers.getUniqueVarName(method.params, ['url', 'url_var']);
|
|
1029
1050
|
const paramGroups = getMethodParamGroup(method);
|
|
1030
1051
|
let body = checkEmptyRequiredPathParams(indent, paramGroups.path);
|
|
1031
1052
|
body += 'let options = options.unwrap_or_default();\n';
|
|
1032
1053
|
body += `${indent.get()}let ctx = options.method_options.context.to_borrowed();\n`;
|
|
1033
|
-
body += `${indent.get()}let ${urlVarNeedsMut(paramGroups, method)}
|
|
1034
|
-
body += constructUrl(indent, use, method, paramGroups);
|
|
1035
|
-
|
|
1054
|
+
body += `${indent.get()}let ${urlVarNeedsMut(paramGroups, method)}${urlVarName} = self.${getEndpointFieldName(client)}.clone();\n`;
|
|
1055
|
+
body += constructUrl(indent, use, method, paramGroups, urlVarName);
|
|
1056
|
+
const requestResult = constructRequest(indent, use, method, paramGroups, false, urlVarName);
|
|
1057
|
+
body += requestResult.content;
|
|
1036
1058
|
let pipelineMethod;
|
|
1037
1059
|
switch (method.returns.type.kind) {
|
|
1038
1060
|
case 'asyncResponse':
|
|
@@ -1042,7 +1064,7 @@ function getAsyncMethodBody(indent, use, client, method) {
|
|
|
1042
1064
|
pipelineMethod = 'send';
|
|
1043
1065
|
break;
|
|
1044
1066
|
}
|
|
1045
|
-
body += `${indent.get()}let rsp = self.pipeline.${pipelineMethod}(&ctx, &mut
|
|
1067
|
+
body += `${indent.get()}let rsp = self.pipeline.${pipelineMethod}(&ctx, &mut ${requestResult.requestVarName}, ${getPipelineOptions(indent, use, method)}).await?;\n`;
|
|
1046
1068
|
body += `${indent.get()}Ok(rsp.into())\n`;
|
|
1047
1069
|
return body;
|
|
1048
1070
|
}
|
|
@@ -1062,19 +1084,23 @@ function getPageableMethodBody(indent, use, client, method) {
|
|
|
1062
1084
|
use.addForType(method.returns.type);
|
|
1063
1085
|
use.addForType(helpers.unwrapType(method.returns.type));
|
|
1064
1086
|
const paramGroups = getMethodParamGroup(method);
|
|
1065
|
-
const urlVar = method.strategy ? 'first_url' : 'url';
|
|
1087
|
+
const urlVar = method.strategy ? 'first_url' : helpers.getUniqueVarName(method.params, ['url', 'url_var']);
|
|
1066
1088
|
let body = checkEmptyRequiredPathParams(indent, paramGroups.path);
|
|
1067
1089
|
body += 'let options = options.unwrap_or_default().into_owned();\n';
|
|
1068
1090
|
body += `${indent.get()}let pipeline = self.pipeline.clone();\n`;
|
|
1069
1091
|
body += `${indent.get()}let ${urlVarNeedsMut(paramGroups, method)}${urlVar} = self.${getEndpointFieldName(client)}.clone();\n`;
|
|
1070
1092
|
body += constructUrl(indent, use, method, paramGroups, urlVar);
|
|
1071
|
-
if (paramGroups.apiVersion) {
|
|
1072
|
-
body += `${indent.get()}let ${paramGroups.apiVersion.name} = ${getHeaderPathQueryParamValue(use, paramGroups.apiVersion, true)}.clone();\n`;
|
|
1073
|
-
}
|
|
1074
1093
|
// passed to constructRequest. we only need to
|
|
1075
1094
|
// clone it for the non-continuation case.
|
|
1076
1095
|
let cloneUrl = false;
|
|
1096
|
+
// this will be either the inner URL var created
|
|
1097
|
+
// during paging or the initial URL var when there's
|
|
1098
|
+
// no paging strategy
|
|
1099
|
+
let srcUrlVar;
|
|
1077
1100
|
if (method.strategy) {
|
|
1101
|
+
if (paramGroups.apiVersion) {
|
|
1102
|
+
body += `${indent.get()}let ${paramGroups.apiVersion.name} = ${getHeaderPathQueryParamValue(use, paramGroups.apiVersion, true, true)}.clone();\n`;
|
|
1103
|
+
}
|
|
1078
1104
|
switch (method.strategy.kind) {
|
|
1079
1105
|
case 'continuationToken': {
|
|
1080
1106
|
const reqTokenParam = method.strategy.requestToken.name;
|
|
@@ -1102,33 +1128,47 @@ function getPageableMethodBody(indent, use, client, method) {
|
|
|
1102
1128
|
}
|
|
1103
1129
|
})}\n`;
|
|
1104
1130
|
}
|
|
1131
|
+
srcUrlVar = 'url';
|
|
1105
1132
|
break;
|
|
1106
1133
|
}
|
|
1107
1134
|
case 'nextLink': {
|
|
1108
1135
|
const nextLinkName = method.strategy.nextLinkPath[method.strategy.nextLinkPath.length - 1].name;
|
|
1136
|
+
const reinjectedParams = method.strategy.reinjectedParams;
|
|
1109
1137
|
body += `${indent.get()}Ok(${method.returns.type.name}::from_callback(move |${nextLinkName}: PagerState<Url>| {\n`;
|
|
1110
1138
|
body += `${indent.push().get()}let url = ` + helpers.buildMatch(indent, nextLinkName, [{
|
|
1111
1139
|
pattern: `PagerState::More(${nextLinkName})`,
|
|
1112
1140
|
body: (indent) => {
|
|
1141
|
+
const cloneNextLink = `${indent.get()}let mut ${nextLinkName} = ${nextLinkName}.clone();\n`;
|
|
1142
|
+
let content = '';
|
|
1113
1143
|
if (paramGroups.apiVersion && paramGroups.apiVersion.kind === 'queryScalar') {
|
|
1114
1144
|
const apiVersionKey = `"${paramGroups.apiVersion.key}"`;
|
|
1115
1145
|
// there are no APIs to set/update an existing query parameter.
|
|
1116
1146
|
// so, we filter the existing query params to remove the api-version
|
|
1117
1147
|
// query param. we then add back the filtered set and then add the
|
|
1118
1148
|
// api-version as specified on the client.
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1149
|
+
content = `${indent.get()}let qp = ${nextLinkName}.query_pairs().filter(|(name, _)| name.ne(${apiVersionKey}));\n`;
|
|
1150
|
+
content += cloneNextLink;
|
|
1151
|
+
content += `${indent.get()}${nextLinkName}.query_pairs_mut().clear().extend_pairs(qp).append_pair(${apiVersionKey}, &${paramGroups.apiVersion.name});\n`;
|
|
1152
|
+
}
|
|
1153
|
+
else if (reinjectedParams.length > 0) {
|
|
1154
|
+
// if we didn't clone it above, we'll need to clone it for this case
|
|
1155
|
+
content += cloneNextLink;
|
|
1124
1156
|
}
|
|
1125
|
-
|
|
1157
|
+
// add query params for reinjection
|
|
1158
|
+
for (const reinjectedParam of reinjectedParams) {
|
|
1159
|
+
content += getParamValueHelper(indent, reinjectedParam, true, () => {
|
|
1160
|
+
return `${indent.get()}${nextLinkName}.query_pairs_mut().append_pair("${reinjectedParam.key}", ${getHeaderPathQueryParamValue(use, reinjectedParam, false, false)});\n`;
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
content += `${indent.get()}${nextLinkName}\n`;
|
|
1164
|
+
return content;
|
|
1126
1165
|
}
|
|
1127
1166
|
}, {
|
|
1128
1167
|
pattern: 'PagerState::Initial',
|
|
1129
1168
|
body: (indent) => `${indent.get()}${urlVar}.clone()\n`
|
|
1130
1169
|
}]);
|
|
1131
1170
|
body += ';\n';
|
|
1171
|
+
srcUrlVar = 'url';
|
|
1132
1172
|
break;
|
|
1133
1173
|
}
|
|
1134
1174
|
}
|
|
@@ -1136,7 +1176,9 @@ function getPageableMethodBody(indent, use, client, method) {
|
|
|
1136
1176
|
else {
|
|
1137
1177
|
// no next link when there's no strategy
|
|
1138
1178
|
body += `${indent.get()}Ok(Pager::from_callback(move |_: PagerState<Url>| {\n`;
|
|
1179
|
+
indent.push();
|
|
1139
1180
|
cloneUrl = true;
|
|
1181
|
+
srcUrlVar = urlVar;
|
|
1140
1182
|
}
|
|
1141
1183
|
// Pipeline::send() returns a RawResponse, so no reason to declare the type if not something else.
|
|
1142
1184
|
let rspType = '';
|
|
@@ -1149,17 +1191,18 @@ function getPageableMethodBody(indent, use, client, method) {
|
|
|
1149
1191
|
rspType = `: ${rspTypeDecl}`;
|
|
1150
1192
|
rspInto = '.into()';
|
|
1151
1193
|
}
|
|
1152
|
-
|
|
1194
|
+
const requestResult = constructRequest(indent, use, method, paramGroups, true, srcUrlVar, cloneUrl);
|
|
1195
|
+
body += requestResult.content;
|
|
1153
1196
|
body += `${indent.get()}let ctx = options.method_options.context.clone();\n`;
|
|
1154
1197
|
body += `${indent.get()}let pipeline = pipeline.clone();\n`;
|
|
1155
1198
|
body += `${indent.get()}async move {\n`;
|
|
1156
|
-
body += `${indent.push().get()}let rsp${rspType} = pipeline.send(&ctx, &mut
|
|
1199
|
+
body += `${indent.push().get()}let rsp${rspType} = pipeline.send(&ctx, &mut ${requestResult.requestVarName}, ${getPipelineOptions(indent, use, method)}).await?${rspInto};\n`;
|
|
1157
1200
|
// check if we need to extract the next link field from the response model
|
|
1158
1201
|
if (method.strategy && (method.strategy.kind === 'nextLink' || method.strategy.responseToken.kind === 'nextLink')) {
|
|
1159
1202
|
const bodyFormat = helpers.convertResponseFormat(method.returns.type.type.format);
|
|
1160
1203
|
use.add('azure_core', bodyFormat, 'http::RawResponse');
|
|
1161
1204
|
body += `${indent.get()}let (status, headers, body) = rsp.deconstruct();\n`;
|
|
1162
|
-
const deserialize = bodyFormat
|
|
1205
|
+
const deserialize = `${bodyFormat}::from_${bodyFormat}`;
|
|
1163
1206
|
body += `${indent.get()}let res: ${helpers.getTypeDeclaration(helpers.unwrapType(method.returns.type))} = ${deserialize}(&body)?;\n`;
|
|
1164
1207
|
body += `${indent.get()}let rsp = RawResponse::from_bytes(status, headers, body).into();\n`;
|
|
1165
1208
|
}
|
|
@@ -1248,17 +1291,19 @@ function getLroMethodBody(indent, use, client, method) {
|
|
|
1248
1291
|
use.addForType(method.returns.type);
|
|
1249
1292
|
use.addForType(helpers.unwrapType(method.returns.type));
|
|
1250
1293
|
const paramGroups = getMethodParamGroup(method);
|
|
1251
|
-
const urlVar = 'url';
|
|
1294
|
+
const urlVar = helpers.getUniqueVarName(method.params, ['url', 'url_var']);
|
|
1252
1295
|
let body = 'let options = options.unwrap_or_default().into_owned();\n';
|
|
1253
1296
|
body += `${indent.get()}let pipeline = self.pipeline.clone();\n`;
|
|
1254
1297
|
body += `${indent.get()}let ${urlVarNeedsMut(paramGroups, method)}${urlVar} = self.${getEndpointFieldName(client)}.clone();\n`;
|
|
1255
1298
|
body += constructUrl(indent, use, method, paramGroups, urlVar);
|
|
1256
1299
|
if (paramGroups.apiVersion) {
|
|
1257
|
-
body += `${indent.get()}let ${paramGroups.apiVersion.name} = ${getHeaderPathQueryParamValue(use, paramGroups.apiVersion, true)}.clone();\n`;
|
|
1300
|
+
body += `${indent.get()}let ${paramGroups.apiVersion.name} = ${getHeaderPathQueryParamValue(use, paramGroups.apiVersion, true, true)}.clone();\n`;
|
|
1258
1301
|
}
|
|
1302
|
+
// we call this eagerly so that we have access to the request var name
|
|
1303
|
+
const initialRequestResult = constructRequest(indent, use, method, paramGroups, true, urlVar, true, false);
|
|
1259
1304
|
body += `${indent.get()}Ok(${method.returns.type.name}::from_callback(\n`;
|
|
1260
1305
|
body += `${indent.push().get()}move |next_link: PollerState<Url>| {\n`;
|
|
1261
|
-
body += `${indent.push().get()}let (mut
|
|
1306
|
+
body += `${indent.push().get()}let (mut ${initialRequestResult.requestVarName}, next_link) = ${helpers.buildMatch(indent, 'next_link', [{
|
|
1262
1307
|
pattern: `PollerState::More(next_link)`,
|
|
1263
1308
|
body: (indent) => {
|
|
1264
1309
|
var _a;
|
|
@@ -1268,33 +1313,33 @@ function getLroMethodBody(indent, use, client, method) {
|
|
|
1268
1313
|
body += `${indent.get()}let mut next_link = next_link.clone();\n`;
|
|
1269
1314
|
body += `${indent.get()}next_link.query_pairs_mut().clear().extend_pairs(qp).append_pair("${paramGroups.apiVersion.key}", &${paramGroups.apiVersion.name});\n`;
|
|
1270
1315
|
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1316
|
+
let mutRequest = '';
|
|
1317
|
+
// if the only header is optional Content-Type it will not be used
|
|
1318
|
+
// by applyHeaderParams() in this case so don't make request mutable
|
|
1319
|
+
if (paramGroups.header.length > 1 || (paramGroups.header.length === 1 && !isOptionalContentTypeHeader(paramGroups.header[0]))) {
|
|
1320
|
+
mutRequest = 'mut ';
|
|
1321
|
+
}
|
|
1322
|
+
body += `${indent.get()}let ${mutRequest}${initialRequestResult.requestVarName} = Request::new(next_link.clone(), Method::Get);\n`;
|
|
1323
|
+
body += applyHeaderParams(indent, use, method, paramGroups, true, initialRequestResult.requestVarName);
|
|
1324
|
+
body += `${indent.get()}(${initialRequestResult.requestVarName}, next_link)\n`;
|
|
1274
1325
|
return body;
|
|
1275
1326
|
},
|
|
1276
1327
|
}, {
|
|
1277
1328
|
pattern: 'PollerState::Initial',
|
|
1278
1329
|
body: (indent) => {
|
|
1279
|
-
let body =
|
|
1280
|
-
body += `${indent.get()}(
|
|
1330
|
+
let body = initialRequestResult.content;
|
|
1331
|
+
body += `${indent.get()}(${initialRequestResult.requestVarName}, url.clone())\n`;
|
|
1281
1332
|
return body;
|
|
1282
1333
|
},
|
|
1283
1334
|
}])};\n`;
|
|
1284
1335
|
body += `${indent.get()}let ctx = options.method_options.context.clone();\n`;
|
|
1285
1336
|
body += `${indent.get()}let pipeline = pipeline.clone();\n`;
|
|
1286
1337
|
body += `${indent.get()}async move {\n`;
|
|
1287
|
-
body += `${indent.push().get()}let rsp = pipeline.send(&ctx, &mut
|
|
1338
|
+
body += `${indent.push().get()}let rsp = pipeline.send(&ctx, &mut ${initialRequestResult.requestVarName}, ${getPipelineOptions(indent, use, method)}).await?;\n`;
|
|
1288
1339
|
body += `${indent.get()}let (status, headers, body) = rsp.deconstruct();\n`;
|
|
1289
1340
|
body += `${indent.get()}let retry_after = get_retry_after(&headers, &[X_MS_RETRY_AFTER_MS, RETRY_AFTER_MS, RETRY_AFTER], &options.poller_options);\n`;
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
use.add('azure_core', 'json');
|
|
1293
|
-
deserialize = 'json::from_json';
|
|
1294
|
-
}
|
|
1295
|
-
else {
|
|
1296
|
-
deserialize = 'xml::read_xml';
|
|
1297
|
-
}
|
|
1341
|
+
const deserialize = `${bodyFormat}::from_${bodyFormat}`;
|
|
1342
|
+
use.add('azure_core', bodyFormat);
|
|
1298
1343
|
body += `${indent.get()}let res: ${helpers.getTypeDeclaration(helpers.unwrapType(method.returns.type))} = ${deserialize}(&body)?;\n`;
|
|
1299
1344
|
body += `${indent.get()}let rsp = RawResponse::from_bytes(status, headers, body).into();\n`;
|
|
1300
1345
|
body += `${indent.get()}Ok(${helpers.buildMatch(indent, 'res.status()', [{
|
|
@@ -1343,8 +1388,9 @@ function getClientSupplementalEndpointParamValue(param) {
|
|
|
1343
1388
|
}
|
|
1344
1389
|
}
|
|
1345
1390
|
/**
|
|
1346
|
-
*
|
|
1347
|
-
* from a parameter of that type.
|
|
1391
|
+
* returns the code to use when populating a header/path/query value
|
|
1392
|
+
* from a parameter of that type. this will include any borrowing of
|
|
1393
|
+
* the parameter (or its calculated result) as required.
|
|
1348
1394
|
*
|
|
1349
1395
|
* if the param's type is a String, then the return value is simply the
|
|
1350
1396
|
* param's name. the non-String cases require some kind of conversion.
|
|
@@ -1354,9 +1400,10 @@ function getClientSupplementalEndpointParamValue(param) {
|
|
|
1354
1400
|
* @param use the use statement builder currently in scope
|
|
1355
1401
|
* @param param the param for which to get the value
|
|
1356
1402
|
* @param fromSelf applicable for client params. when true, the prefix "self." is included
|
|
1403
|
+
* @param neverBorrow indicates that the borrowing calculation should be skipped
|
|
1357
1404
|
* @returns the code to use for the param's value
|
|
1358
1405
|
*/
|
|
1359
|
-
function getHeaderPathQueryParamValue(use, param, fromSelf) {
|
|
1406
|
+
function getHeaderPathQueryParamValue(use, param, fromSelf, neverBorrow) {
|
|
1360
1407
|
let paramName = param.name;
|
|
1361
1408
|
// when fromSelf is false we assume that there's a local with the same name.
|
|
1362
1409
|
// e.g. in pageable methods where we need to clone the params so they can be
|
|
@@ -1371,64 +1418,102 @@ function getHeaderPathQueryParamValue(use, param, fromSelf) {
|
|
|
1371
1418
|
}
|
|
1372
1419
|
return encoding;
|
|
1373
1420
|
};
|
|
1374
|
-
const encodeDateTime = function (type,
|
|
1421
|
+
const encodeDateTime = function (type, paramName) {
|
|
1375
1422
|
const encoding = helpers.getDateTimeEncodingMethod(type.encoding, 'to', use);
|
|
1376
1423
|
switch (type.encoding) {
|
|
1377
1424
|
case 'rfc3339':
|
|
1378
1425
|
case 'rfc7231': {
|
|
1379
|
-
return `${encoding}(
|
|
1426
|
+
return `${encoding}(${param.type.kind === 'ref' ? '' : '&'}${paramName})`;
|
|
1380
1427
|
}
|
|
1381
1428
|
case 'unix_time':
|
|
1382
|
-
return `${
|
|
1429
|
+
return `${paramName}.${encoding}.to_string()`;
|
|
1383
1430
|
}
|
|
1384
1431
|
};
|
|
1432
|
+
// this will contain the final text for
|
|
1433
|
+
// retrieving the param value. this will include
|
|
1434
|
+
// any required conversions and/or borrowing
|
|
1435
|
+
let paramValue;
|
|
1436
|
+
// contains the result from calculating if the
|
|
1437
|
+
// param requires borrowing.
|
|
1438
|
+
let mustBorrow = true;
|
|
1385
1439
|
const paramType = helpers.unwrapType(param.type);
|
|
1386
1440
|
if (param.kind === 'headerCollection' || param.kind === 'queryCollection') {
|
|
1387
1441
|
if (param.format === 'multi') {
|
|
1388
1442
|
throw new CodegenError('InternalError', 'multi should have been handled outside getHeaderPathQueryParamValue');
|
|
1389
1443
|
}
|
|
1390
1444
|
else if (paramType.kind === 'String' || paramType.kind === 'str') {
|
|
1391
|
-
|
|
1445
|
+
paramValue = `${paramName}.join("${getCollectionDelimiter(param.format)}")`;
|
|
1392
1446
|
}
|
|
1393
|
-
|
|
1394
|
-
|
|
1447
|
+
else {
|
|
1448
|
+
// convert the items to strings
|
|
1449
|
+
let strConv;
|
|
1450
|
+
switch (paramType.kind) {
|
|
1451
|
+
case 'encodedBytes':
|
|
1452
|
+
strConv = encodeBytes(paramType);
|
|
1453
|
+
break;
|
|
1454
|
+
case 'offsetDateTime':
|
|
1455
|
+
strConv = `|i| ${encodeDateTime(paramType, 'i')}`;
|
|
1456
|
+
break;
|
|
1457
|
+
default:
|
|
1458
|
+
strConv = '|i| i.to_string()';
|
|
1459
|
+
}
|
|
1460
|
+
paramValue = `${param.name}.iter().map(${strConv}).collect::<Vec<String>>().join("${getCollectionDelimiter(param.format)}")`;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
else {
|
|
1395
1464
|
switch (paramType.kind) {
|
|
1465
|
+
case 'String':
|
|
1466
|
+
paramValue = paramName;
|
|
1467
|
+
// if the param is on the client, or it's optional, then we must borrow
|
|
1468
|
+
mustBorrow = (param.location === 'client' && fromSelf) || param.optional;
|
|
1469
|
+
break;
|
|
1470
|
+
case 'str':
|
|
1471
|
+
paramValue = paramName;
|
|
1472
|
+
// str is already borrowed
|
|
1473
|
+
mustBorrow = false;
|
|
1474
|
+
break;
|
|
1475
|
+
case 'decimal':
|
|
1476
|
+
paramValue = `${param.name}.to_string()`;
|
|
1477
|
+
break;
|
|
1396
1478
|
case 'encodedBytes':
|
|
1397
|
-
|
|
1479
|
+
paramValue = encodeBytes(paramType, paramName);
|
|
1480
|
+
break;
|
|
1481
|
+
case 'enum':
|
|
1482
|
+
case 'scalar':
|
|
1483
|
+
if (paramType.kind === 'enum' && (param.kind === 'pathScalar' || param.kind === 'queryScalar')) {
|
|
1484
|
+
// append_pair and path.replace() want a reference to the string
|
|
1485
|
+
// TODO: https://github.com/Azure/typespec-rust/issues/25
|
|
1486
|
+
paramValue = `${paramName}.as_ref()`;
|
|
1487
|
+
// as_ref() elides the need to borrow
|
|
1488
|
+
mustBorrow = false;
|
|
1489
|
+
}
|
|
1490
|
+
else {
|
|
1491
|
+
paramValue = `${paramName}.to_string()`;
|
|
1492
|
+
}
|
|
1493
|
+
break;
|
|
1494
|
+
case 'enumValue':
|
|
1495
|
+
paramValue = `${paramType.type.name}::${paramType.name}.to_string()`;
|
|
1496
|
+
break;
|
|
1497
|
+
case 'literal':
|
|
1498
|
+
paramValue = `"${paramType.value}"`;
|
|
1398
1499
|
break;
|
|
1399
1500
|
case 'offsetDateTime':
|
|
1400
|
-
|
|
1501
|
+
paramValue = encodeDateTime(paramType, param.name);
|
|
1401
1502
|
break;
|
|
1402
1503
|
default:
|
|
1403
|
-
|
|
1504
|
+
throw new CodegenError('InternalError', `unhandled ${param.kind} param type kind ${paramType.kind}`);
|
|
1404
1505
|
}
|
|
1405
|
-
return `${param.name}.iter().map(${strConv}).collect::<Vec<String>>().join("${getCollectionDelimiter(param.format)}")`;
|
|
1406
1506
|
}
|
|
1407
|
-
switch (
|
|
1408
|
-
case '
|
|
1409
|
-
case '
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
case 'enum':
|
|
1416
|
-
case 'scalar':
|
|
1417
|
-
if (paramType.kind === 'enum' && (param.kind === 'pathScalar' || param.kind === 'queryScalar')) {
|
|
1418
|
-
// append_pair and path.replace() want a reference to the string
|
|
1419
|
-
// TODO: https://github.com/Azure/typespec-rust/issues/25
|
|
1420
|
-
return `${paramName}.as_ref()`;
|
|
1421
|
-
}
|
|
1422
|
-
return `${paramName}.to_string()`;
|
|
1423
|
-
case 'enumValue':
|
|
1424
|
-
return `${paramType.type.name}::${paramType.name}.to_string()`;
|
|
1425
|
-
case 'literal':
|
|
1426
|
-
return `"${paramType.value}"`;
|
|
1427
|
-
case 'offsetDateTime':
|
|
1428
|
-
return encodeDateTime(paramType, param.name);
|
|
1429
|
-
default:
|
|
1430
|
-
throw new CodegenError('InternalError', `unhandled ${param.kind} param type kind ${paramType.kind}`);
|
|
1507
|
+
switch (param.kind) {
|
|
1508
|
+
case 'headerCollection':
|
|
1509
|
+
case 'headerHashMap':
|
|
1510
|
+
case 'headerScalar':
|
|
1511
|
+
// for non-copyable params (e.g. String), we need to borrow them if they're on the
|
|
1512
|
+
// client or we're in a closure and the param is required (header params are always owned)
|
|
1513
|
+
mustBorrow = nonCopyableType(param.type) && (param.location === 'client' || (!fromSelf && !param.optional));
|
|
1514
|
+
break;
|
|
1431
1515
|
}
|
|
1516
|
+
return `${mustBorrow && !neverBorrow ? '&' : ''}${paramValue}`;
|
|
1432
1517
|
}
|
|
1433
1518
|
/**
|
|
1434
1519
|
* returns the delimiter character for the provided format type
|
|
@@ -1448,7 +1533,7 @@ function getCollectionDelimiter(format) {
|
|
|
1448
1533
|
return '\t';
|
|
1449
1534
|
}
|
|
1450
1535
|
}
|
|
1451
|
-
/** returns true if the type isn't copyable thus needs to be cloned */
|
|
1536
|
+
/** returns true if the type isn't copyable thus needs to be cloned or borrowed */
|
|
1452
1537
|
function nonCopyableType(type) {
|
|
1453
1538
|
const unwrappedType = shared.unwrapOption(type);
|
|
1454
1539
|
switch (unwrappedType.kind) {
|