@azure-tools/typespec-rust 0.13.3 → 0.14.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 +155 -85
- 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 -2
- package/dist/src/codegen/context.js.map +1 -1
- package/dist/src/codegen/errors.d.ts +13 -0
- package/dist/src/codegen/errors.d.ts.map +1 -0
- package/dist/src/codegen/errors.js +15 -0
- package/dist/src/codegen/errors.js.map +1 -0
- package/dist/src/codegen/headerTraits.d.ts.map +1 -1
- package/dist/src/codegen/headerTraits.js +3 -2
- package/dist/src/codegen/headerTraits.js.map +1 -1
- package/dist/src/codegen/helpers.d.ts.map +1 -1
- package/dist/src/codegen/helpers.js +13 -3
- package/dist/src/codegen/helpers.js.map +1 -1
- package/dist/src/codegen/models.d.ts.map +1 -1
- package/dist/src/codegen/models.js +133 -71
- package/dist/src/codegen/models.js.map +1 -1
- package/dist/src/codegen/use.d.ts.map +1 -1
- package/dist/src/codegen/use.js +4 -2
- package/dist/src/codegen/use.js.map +1 -1
- package/dist/src/codemodel/client.d.ts +17 -31
- package/dist/src/codemodel/client.d.ts.map +1 -1
- package/dist/src/codemodel/client.js +1 -35
- package/dist/src/codemodel/client.js.map +1 -1
- package/dist/src/codemodel/method.d.ts +0 -2
- package/dist/src/codemodel/method.d.ts.map +1 -1
- package/dist/src/codemodel/method.js +0 -1
- package/dist/src/codemodel/method.js.map +1 -1
- package/dist/src/codemodel/types.d.ts +52 -5
- package/dist/src/codemodel/types.d.ts.map +1 -1
- package/dist/src/codemodel/types.js +26 -7
- package/dist/src/codemodel/types.js.map +1 -1
- package/dist/src/emitter.d.ts.map +1 -1
- package/dist/src/emitter.js +84 -34
- package/dist/src/emitter.js.map +1 -1
- package/dist/src/lib.d.ts +37 -4
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +27 -2
- package/dist/src/lib.js.map +1 -1
- package/dist/src/tcgcadapter/adapter.d.ts +58 -10
- package/dist/src/tcgcadapter/adapter.d.ts.map +1 -1
- package/dist/src/tcgcadapter/adapter.js +390 -176
- package/dist/src/tcgcadapter/adapter.js.map +1 -1
- package/dist/src/tcgcadapter/helpers.d.ts +8 -0
- package/dist/src/tcgcadapter/helpers.d.ts.map +1 -1
- package/dist/src/tcgcadapter/helpers.js +13 -0
- package/dist/src/tcgcadapter/helpers.js.map +1 -1
- package/package.json +22 -24
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../../src/codegen/clients.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../../src/codegen/clients.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAGxC,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAE9C,yBAAyB;AACzB,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,aAAa,GAAG,SAAS,CAoPxE"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as codegen from '@azure-tools/codegen';
|
|
6
6
|
import { values } from '@azure-tools/linq';
|
|
7
|
+
import { CodegenError } from './errors.js';
|
|
7
8
|
import * as helpers from './helpers.js';
|
|
8
9
|
import queryString from 'query-string';
|
|
9
10
|
import { Use } from './use.js';
|
|
@@ -112,7 +113,7 @@ export function emitClients(crate) {
|
|
|
112
113
|
continue;
|
|
113
114
|
}
|
|
114
115
|
if (!client.fields.find((v) => { return v.name === param.name; })) {
|
|
115
|
-
throw new
|
|
116
|
+
throw new CodegenError('InternalError', `didn't find field in client ${client.name} for param ${param.name}`);
|
|
116
117
|
}
|
|
117
118
|
// by convention, the param field and param name are the
|
|
118
119
|
// same so we can use shorthand initialization syntax
|
|
@@ -124,10 +125,10 @@ export function emitClients(crate) {
|
|
|
124
125
|
continue;
|
|
125
126
|
}
|
|
126
127
|
if (!client.fields.find((v) => { return v.name === param.name; })) {
|
|
127
|
-
throw new
|
|
128
|
+
throw new CodegenError('InternalError', `didn't find field in client ${client.name} for param ${param.name}`);
|
|
128
129
|
}
|
|
129
130
|
if (!client.constructable.options.type.fields.find((v) => { return v.name === param.name; })) {
|
|
130
|
-
throw new
|
|
131
|
+
throw new CodegenError('InternalError', `didn't find field in client options ${client.constructable.options.type.name} for optional param ${param.name}`);
|
|
131
132
|
}
|
|
132
133
|
body += `${indent.get()}${param.name}: options.${param.name},\n`;
|
|
133
134
|
}
|
|
@@ -349,11 +350,7 @@ function getConstructorParamsSig(params, options, use) {
|
|
|
349
350
|
continue;
|
|
350
351
|
}
|
|
351
352
|
use.addForType(param.type);
|
|
352
|
-
|
|
353
|
-
if (param.kind === 'clientMethod' && param.ref) {
|
|
354
|
-
ref = '&';
|
|
355
|
-
}
|
|
356
|
-
paramsSig.push(`${param.name}: ${ref}${helpers.getTypeDeclaration(param.type)}`);
|
|
353
|
+
paramsSig.push(`${param.name}: ${helpers.getTypeDeclaration(param.type)}`);
|
|
357
354
|
}
|
|
358
355
|
paramsSig.push(`options: ${helpers.getTypeDeclaration(options)}`);
|
|
359
356
|
return paramsSig.join(', ');
|
|
@@ -379,13 +376,14 @@ function getMethodParamsSig(method, use) {
|
|
|
379
376
|
}
|
|
380
377
|
else {
|
|
381
378
|
for (const param of method.params) {
|
|
382
|
-
|
|
379
|
+
const paramType = helpers.unwrapType(param.type);
|
|
380
|
+
if (paramType.kind === 'literal') {
|
|
383
381
|
// literal params are embedded directly in the code (e.g. accept header param)
|
|
384
382
|
continue;
|
|
385
383
|
}
|
|
386
|
-
else if (
|
|
384
|
+
else if (paramType.kind === 'enumValue') {
|
|
387
385
|
// enum values are treated like literals, we just need to use their type
|
|
388
|
-
use.addForType(
|
|
386
|
+
use.addForType(paramType.type);
|
|
389
387
|
continue;
|
|
390
388
|
}
|
|
391
389
|
// don't add client or optional params to the method param sig
|
|
@@ -428,7 +426,7 @@ function getAuthPolicy(ctor, use) {
|
|
|
428
426
|
*/
|
|
429
427
|
function formatParamTypeName(param) {
|
|
430
428
|
let format = '';
|
|
431
|
-
if (param.ref) {
|
|
429
|
+
if (param.ref === true) {
|
|
432
430
|
format = '&';
|
|
433
431
|
}
|
|
434
432
|
if (param.mut) {
|
|
@@ -462,13 +460,13 @@ function getEndpointFieldName(client) {
|
|
|
462
460
|
for (const field of client.fields) {
|
|
463
461
|
if (field.type.kind === 'Url') {
|
|
464
462
|
if (endpointFieldName) {
|
|
465
|
-
throw new
|
|
463
|
+
throw new CodegenError('InternalError', `found multiple URL fields in client ${client.name} which is unexpected`);
|
|
466
464
|
}
|
|
467
465
|
endpointFieldName = field.name;
|
|
468
466
|
}
|
|
469
467
|
}
|
|
470
468
|
if (!endpointFieldName) {
|
|
471
|
-
throw new
|
|
469
|
+
throw new CodegenError('InternalError', `didn't find URI field for client ${client.name}`);
|
|
472
470
|
}
|
|
473
471
|
return endpointFieldName;
|
|
474
472
|
}
|
|
@@ -533,7 +531,7 @@ function getMethodParamGroup(method) {
|
|
|
533
531
|
queryParams.push(param);
|
|
534
532
|
break;
|
|
535
533
|
}
|
|
536
|
-
if (param.kind === 'query' && param.isApiVersion) {
|
|
534
|
+
if ((param.kind === 'header' || param.kind === 'query') && param.isApiVersion) {
|
|
537
535
|
apiVersionParam = param;
|
|
538
536
|
}
|
|
539
537
|
}
|
|
@@ -544,7 +542,7 @@ function getMethodParamGroup(method) {
|
|
|
544
542
|
for (const param of method.params) {
|
|
545
543
|
if (param.kind === 'body') {
|
|
546
544
|
if (bodyParam) {
|
|
547
|
-
throw new
|
|
545
|
+
throw new CodegenError('InternalError', `method ${method.name} has multiple body parameters`);
|
|
548
546
|
}
|
|
549
547
|
bodyParam = param;
|
|
550
548
|
}
|
|
@@ -568,13 +566,14 @@ function getMethodParamGroup(method) {
|
|
|
568
566
|
* @param indent the indentation helper currently in scope
|
|
569
567
|
* @param param the parameter to which the contents of setter apply
|
|
570
568
|
* @param setter the callback that emits the code to read from a param var
|
|
569
|
+
* @param inClosure indicates if the value is being read from within a closure (e.g. pageable methods)
|
|
571
570
|
* @returns
|
|
572
571
|
*/
|
|
573
|
-
function getParamValueHelper(indent, param, setter) {
|
|
572
|
+
function getParamValueHelper(indent, param, inClosure, setter) {
|
|
574
573
|
if (param.optional) {
|
|
575
574
|
// optional params are in the unwrapped options local var
|
|
576
575
|
const op = indent.get() + helpers.buildIfBlock(indent, {
|
|
577
|
-
condition: `let Some(${param.name}) = options.${param.name}`,
|
|
576
|
+
condition: `let Some(${param.name}) = ${inClosure ? '&' : ''}options.${param.name}`,
|
|
578
577
|
body: setter,
|
|
579
578
|
});
|
|
580
579
|
return op + '\n';
|
|
@@ -596,11 +595,14 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
596
595
|
// including them in the call to set_path() causes the chars to be path-escaped.
|
|
597
596
|
const pathChunks = method.httpPath.split('?');
|
|
598
597
|
if (pathChunks.length > 2) {
|
|
599
|
-
throw new
|
|
598
|
+
throw new CodegenError('InternalError', 'too many HTTP path chunks');
|
|
600
599
|
}
|
|
601
600
|
/** returns & if the param needs to be borrowed (which is the majority of cases), else the empty string */
|
|
602
601
|
const borrowOrNot = function (param) {
|
|
603
|
-
|
|
602
|
+
if (param.type.kind !== 'ref' || param.type.type.kind === 'encodedBytes' || param.type.type.kind === 'slice') {
|
|
603
|
+
return '&';
|
|
604
|
+
}
|
|
605
|
+
return '';
|
|
604
606
|
};
|
|
605
607
|
let body = '';
|
|
606
608
|
// if path is just "/" no need to set it again, we're already there
|
|
@@ -649,7 +651,7 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
649
651
|
}
|
|
650
652
|
for (const queryParam of paramGroups.query) {
|
|
651
653
|
if (queryParam.kind === 'queryCollection' && queryParam.format === 'multi') {
|
|
652
|
-
body += getParamValueHelper(indent, queryParam, () => {
|
|
654
|
+
body += getParamValueHelper(indent, queryParam, false, () => {
|
|
653
655
|
const valueVar = queryParam.name[0];
|
|
654
656
|
let text = `${indent.get()}for ${valueVar} in ${queryParam.name}.iter() {\n`;
|
|
655
657
|
text += `${indent.push().get()}${urlVarName}.query_pairs_mut().append_pair("${queryParam.key}", ${valueVar});\n`;
|
|
@@ -658,7 +660,7 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
658
660
|
});
|
|
659
661
|
}
|
|
660
662
|
else {
|
|
661
|
-
body += getParamValueHelper(indent, queryParam, () => {
|
|
663
|
+
body += getParamValueHelper(indent, queryParam, false, () => {
|
|
662
664
|
// for enums we call .as_ref() which elides the need to borrow
|
|
663
665
|
const borrow = queryParam.type.kind === 'enum' ? '' : borrowOrNot(queryParam);
|
|
664
666
|
return `${indent.get()}${urlVarName}.query_pairs_mut().append_pair("${queryParam.key}", ${borrow}${getHeaderPathQueryParamValue(use, queryParam, !queryParam.optional)});\n`;
|
|
@@ -676,13 +678,24 @@ function constructUrl(indent, use, method, paramGroups, urlVarName = 'url') {
|
|
|
676
678
|
* @param use the use statement builder currently in scope
|
|
677
679
|
* @param method the method for which we're building the body
|
|
678
680
|
* @param paramGroups the param groups for the provided method
|
|
679
|
-
* @param
|
|
681
|
+
* @param inClosure indicates if the request is being constructed within a closure (e.g. pageable methods)
|
|
680
682
|
* @returns the request construction code
|
|
681
683
|
*/
|
|
682
|
-
function constructRequest(indent, use, method, paramGroups,
|
|
684
|
+
function constructRequest(indent, use, method, paramGroups, inClosure) {
|
|
685
|
+
var _a, _b, _c;
|
|
683
686
|
let body = `${indent.get()}let mut request = Request::new(url, Method::${codegen.capitalize(method.httpMethod)});\n`;
|
|
684
687
|
for (const headerParam of paramGroups.header) {
|
|
685
|
-
|
|
688
|
+
if (method.kind === 'pageable' && ((_a = method.strategy) === null || _a === void 0 ? void 0 : _a.kind) === 'continuationToken' && ((_b = method.strategy) === null || _b === void 0 ? void 0 : _b.requestToken.kind) === 'header' && ((_c = method.strategy) === null || _c === void 0 ? void 0 : _c.requestToken) === headerParam) {
|
|
689
|
+
// we have some special handling for the header continuation token.
|
|
690
|
+
// if we have a token value, i.e. from the next page, then use that value.
|
|
691
|
+
// if not, then check if an optional token value was provided.
|
|
692
|
+
body += indent.get() + helpers.buildIfBlock(indent, {
|
|
693
|
+
condition: `let Some(${headerParam.name}) = ${headerParam.name}.or_else(|| options.${headerParam.name}.clone())`,
|
|
694
|
+
body: (indent) => `${indent.get()}request.insert_header("${headerParam.header}", ${headerParam.name});\n`,
|
|
695
|
+
});
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
body += getParamValueHelper(indent, headerParam, inClosure, () => {
|
|
686
699
|
if (headerParam.kind === 'headerHashMap') {
|
|
687
700
|
let setter = `for (k, v) in &${headerParam.name} {\n`;
|
|
688
701
|
setter += `${indent.push().get()}request.insert_header(format!("${headerParam.header}-{}", k), v);\n`;
|
|
@@ -690,14 +703,13 @@ function constructRequest(indent, use, method, paramGroups, fromSelf = true) {
|
|
|
690
703
|
return setter;
|
|
691
704
|
}
|
|
692
705
|
const borrow = headerParam.location === 'client' && nonCopyableType(headerParam.type) ? '&' : '';
|
|
693
|
-
|
|
694
|
-
return `${indent.get()}request.insert_header("${headerParam.header.toLowerCase()}", ${borrow}${getHeaderPathQueryParamValue(use, headerParam, fromSelf)}${toOwned});\n`;
|
|
706
|
+
return `${indent.get()}request.insert_header("${headerParam.header.toLowerCase()}", ${borrow}${getHeaderPathQueryParamValue(use, headerParam, !inClosure)});\n`;
|
|
695
707
|
});
|
|
696
708
|
}
|
|
697
709
|
const bodyParam = paramGroups.body;
|
|
698
710
|
if (bodyParam) {
|
|
699
|
-
body += getParamValueHelper(indent, bodyParam, () => {
|
|
700
|
-
return `${indent.get()}request.set_body(${bodyParam.name});\n`;
|
|
711
|
+
body += getParamValueHelper(indent, bodyParam, inClosure, () => {
|
|
712
|
+
return `${indent.get()}request.set_body(${bodyParam.name}${inClosure ? '.clone()' : ''});\n`;
|
|
701
713
|
});
|
|
702
714
|
}
|
|
703
715
|
else if (paramGroups.partialBody.length > 0) {
|
|
@@ -708,16 +720,13 @@ function constructRequest(indent, use, method, paramGroups, fromSelf = true) {
|
|
|
708
720
|
indent.push();
|
|
709
721
|
for (const partialBodyParam of paramGroups.partialBody) {
|
|
710
722
|
if (partialBodyParam.type.content.type !== requestContentType.content.type) {
|
|
711
|
-
throw new
|
|
723
|
+
throw new CodegenError('InternalError', `spread param ${partialBodyParam.name} has conflicting model type ${partialBodyParam.type.content.type.name}, expected model type ${requestContentType.content.type.name}`);
|
|
712
724
|
}
|
|
713
725
|
if (partialBodyParam.optional) {
|
|
714
726
|
body += `${indent.get()}${partialBodyParam.name}: options.${partialBodyParam.name},\n`;
|
|
715
727
|
continue;
|
|
716
728
|
}
|
|
717
729
|
let initializer = partialBodyParam.name;
|
|
718
|
-
if (partialBodyParam.ref) {
|
|
719
|
-
initializer = `${initializer}.to_owned()`;
|
|
720
|
-
}
|
|
721
730
|
if (requestContentType.content.type.visibility === 'pub') {
|
|
722
731
|
// spread param maps to a non-internal model, so it must be wrapped in Some()
|
|
723
732
|
initializer = `Some(${initializer})`;
|
|
@@ -761,7 +770,7 @@ function getAsyncMethodBody(indent, use, client, method) {
|
|
|
761
770
|
body += `${indent.get()}let ctx = Context::with_context(&options.method_options.context);\n`;
|
|
762
771
|
body += `${indent.get()}let ${urlVarNeedsMut(paramGroups, method)}url = self.${getEndpointFieldName(client)}.clone();\n`;
|
|
763
772
|
body += constructUrl(indent, use, method, paramGroups);
|
|
764
|
-
body += constructRequest(indent, use, method, paramGroups);
|
|
773
|
+
body += constructRequest(indent, use, method, paramGroups, false);
|
|
765
774
|
body += `${indent.get()}self.pipeline.send(&ctx, &mut request).await\n`;
|
|
766
775
|
return body;
|
|
767
776
|
}
|
|
@@ -776,14 +785,10 @@ function getAsyncMethodBody(indent, use, client, method) {
|
|
|
776
785
|
*/
|
|
777
786
|
function getPageableMethodBody(indent, use, client, method) {
|
|
778
787
|
if (!method.strategy) {
|
|
779
|
-
throw new
|
|
780
|
-
}
|
|
781
|
-
else if (method.strategy.kind !== 'nextLink') {
|
|
782
|
-
throw new Error('paged methods other than nextLink NYI');
|
|
788
|
+
throw new CodegenError('InternalError', 'paged method with no strategy NYI');
|
|
783
789
|
}
|
|
784
|
-
const nextLinkName = method.strategy.nextLink.name;
|
|
785
790
|
use.add('azure_core::http', 'Method', 'Pager', 'PagerResult', 'Request', 'Response', 'Url');
|
|
786
|
-
use.add('azure_core',
|
|
791
|
+
use.add('azure_core', method.returns.type.type.format, 'Result');
|
|
787
792
|
use.addForType(method.returns.type.type.type);
|
|
788
793
|
const paramGroups = getMethodParamGroup(method);
|
|
789
794
|
const urlVar = 'first_url';
|
|
@@ -794,44 +799,108 @@ function getPageableMethodBody(indent, use, client, method) {
|
|
|
794
799
|
if (paramGroups.apiVersion) {
|
|
795
800
|
body += `${indent.get()}let ${paramGroups.apiVersion.name} = ${getHeaderPathQueryParamValue(use, paramGroups.apiVersion, true)}.clone();\n`;
|
|
796
801
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
body
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
802
|
+
switch (method.strategy.kind) {
|
|
803
|
+
case 'continuationToken': {
|
|
804
|
+
const reqTokenParam = method.strategy.requestToken.name;
|
|
805
|
+
body += `${indent.get()}Ok(Pager::from_callback(move |${reqTokenParam}: Option<String>| {\n`;
|
|
806
|
+
body += `${indent.push().get()}let ${method.strategy.requestToken.kind === 'query' ? 'mut ' : ''}url = first_url.clone();\n`;
|
|
807
|
+
if (method.strategy.requestToken.kind === 'query') {
|
|
808
|
+
// if the url already contains the token query param,
|
|
809
|
+
// e.g. we started on some page, then we need to remove
|
|
810
|
+
// it before appending the token for the next page.
|
|
811
|
+
const reqTokenValue = method.strategy.requestToken.key;
|
|
812
|
+
body += `${indent.get()}${helpers.buildIfBlock(indent, {
|
|
813
|
+
condition: `let Some(${reqTokenParam}) = ${reqTokenParam}`,
|
|
814
|
+
body: (indent) => {
|
|
815
|
+
let body = indent.get() + helpers.buildIfBlock(indent, {
|
|
816
|
+
condition: `url.query_pairs().any(|(name, _)| name.eq("${reqTokenValue}"))`,
|
|
817
|
+
body: (indent) => {
|
|
818
|
+
let body = `${indent.get()}let mut new_url = url.clone();\n`;
|
|
819
|
+
body += `${indent.get()}new_url.query_pairs_mut().clear().extend_pairs(url.query_pairs().filter(|(name, _)| name.ne("${reqTokenValue}")));\n`;
|
|
820
|
+
body += `${indent.get()}url = new_url;\n`;
|
|
821
|
+
return body;
|
|
822
|
+
},
|
|
823
|
+
});
|
|
824
|
+
body += `${indent.get()}url.query_pairs_mut().append_pair("${reqTokenValue}", &${reqTokenParam});\n`;
|
|
825
|
+
return body;
|
|
826
|
+
}
|
|
827
|
+
})}`;
|
|
814
828
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
case 'nextLink': {
|
|
832
|
+
const nextLinkName = method.strategy.nextLink.name;
|
|
833
|
+
body += `${indent.get()}Ok(Pager::from_callback(move |${nextLinkName}: Option<Url>| {\n`;
|
|
834
|
+
body += `${indent.push().get()}let url = ` + helpers.buildMatch(indent, nextLinkName, [{
|
|
835
|
+
pattern: `Some(${nextLinkName})`,
|
|
836
|
+
body: (indent) => {
|
|
837
|
+
if (paramGroups.apiVersion && paramGroups.apiVersion.kind === 'query') {
|
|
838
|
+
const apiVersionKey = `"${paramGroups.apiVersion.key}"`;
|
|
839
|
+
// there are no APIs to set/update an existing query parameter.
|
|
840
|
+
// so, we filter the existing query params to remove the api-version
|
|
841
|
+
// query param. we then add back the filtered set and then add the
|
|
842
|
+
// api-version as specified on the client.
|
|
843
|
+
let setApiVerBody = `${indent.get()}let qp = ${nextLinkName}.query_pairs().filter(|(name, _)| name.ne(${apiVersionKey}));\n`;
|
|
844
|
+
setApiVerBody += `${indent.get()}let mut ${nextLinkName} = ${nextLinkName}.clone();\n`;
|
|
845
|
+
setApiVerBody += `${indent.get()}${nextLinkName}.query_pairs_mut().clear().extend_pairs(qp).append_pair(${apiVersionKey}, &${paramGroups.apiVersion.name});\n`;
|
|
846
|
+
setApiVerBody += `${indent.get()}${nextLinkName}\n`;
|
|
847
|
+
return setApiVerBody;
|
|
848
|
+
}
|
|
849
|
+
return `${indent.get()} ${nextLinkName}\n`;
|
|
850
|
+
}
|
|
851
|
+
}, {
|
|
852
|
+
pattern: 'None',
|
|
853
|
+
body: (indent) => `${indent.get()}${urlVar}.clone()\n`
|
|
854
|
+
}]);
|
|
855
|
+
body += ';\n';
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
820
859
|
// here we want the T in Pager<T>
|
|
821
860
|
const returnType = helpers.getTypeDeclaration(method.returns.type.type.type);
|
|
822
|
-
body += constructRequest(indent, use, method, paramGroups,
|
|
861
|
+
body += constructRequest(indent, use, method, paramGroups, true);
|
|
823
862
|
body += `${indent.get()}let ctx = options.method_options.context.clone();\n`;
|
|
824
863
|
body += `${indent.get()}let pipeline = pipeline.clone();\n`;
|
|
825
864
|
body += `${indent.get()}async move {\n`;
|
|
826
865
|
body += `${indent.push().get()}let rsp: Response<${returnType}> = pipeline.send(&ctx, &mut request).await?;\n`;
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
866
|
+
// check if we need to extract the next link field from the response model
|
|
867
|
+
if (method.strategy.kind === 'nextLink' || method.strategy.responseToken.kind === 'modelField') {
|
|
868
|
+
body += `${indent.get()}let (status, headers, body) = rsp.deconstruct();\n`;
|
|
869
|
+
body += `${indent.get()}let bytes = body.collect().await?;\n`;
|
|
870
|
+
const deserialize = method.returns.type.type.format === 'json' ? 'json::from_json' : 'xml::read_xml';
|
|
871
|
+
body += `${indent.get()}let res: ${returnType} = ${deserialize}(&bytes)?;\n`;
|
|
872
|
+
body += `${indent.get()}let rsp = Response::from_bytes(status, headers, bytes);\n`;
|
|
873
|
+
}
|
|
874
|
+
let matchCondition;
|
|
875
|
+
let nextPageValue;
|
|
876
|
+
let continuation;
|
|
877
|
+
switch (method.strategy.kind) {
|
|
878
|
+
case 'continuationToken':
|
|
879
|
+
nextPageValue = method.strategy.responseToken.name;
|
|
880
|
+
continuation = nextPageValue;
|
|
881
|
+
switch (method.strategy.responseToken.kind) {
|
|
882
|
+
case 'modelField':
|
|
883
|
+
matchCondition = `res.${nextPageValue}`;
|
|
884
|
+
break;
|
|
885
|
+
case 'responseHeaderScalar':
|
|
886
|
+
if (!method.responseHeaders) {
|
|
887
|
+
throw new CodegenError('InternalError', `missing response headers trait for method ${method.name}`);
|
|
888
|
+
}
|
|
889
|
+
use.addForType(method.responseHeaders);
|
|
890
|
+
matchCondition = `rsp.${method.strategy.responseToken.name}()?`;
|
|
891
|
+
break;
|
|
892
|
+
}
|
|
893
|
+
break;
|
|
894
|
+
case 'nextLink':
|
|
895
|
+
nextPageValue = method.strategy.nextLink.name;
|
|
896
|
+
matchCondition = `res.${nextPageValue}`;
|
|
897
|
+
continuation = `${nextPageValue}.parse()?`;
|
|
898
|
+
break;
|
|
899
|
+
}
|
|
900
|
+
body += `${indent.get()}Ok(${helpers.buildMatch(indent, matchCondition, [{
|
|
901
|
+
pattern: `Some(${nextPageValue})`,
|
|
833
902
|
returns: 'PagerResult::Continue',
|
|
834
|
-
body: (indent) => `${indent.get()}response: rsp,\n${indent.get()}continuation: ${
|
|
903
|
+
body: (indent) => `${indent.get()}response: rsp,\n${indent.get()}continuation: ${continuation},\n`
|
|
835
904
|
}, {
|
|
836
905
|
pattern: 'None',
|
|
837
906
|
returns: 'PagerResult::Complete',
|
|
@@ -862,7 +931,7 @@ function getClientEndpointParamValue(param) {
|
|
|
862
931
|
case 'scalar':
|
|
863
932
|
return `&${paramName}.to_string()`;
|
|
864
933
|
default:
|
|
865
|
-
throw new
|
|
934
|
+
throw new CodegenError('InternalError', `unhandled ${param.kind} param type kind ${param.type.kind}`);
|
|
866
935
|
}
|
|
867
936
|
}
|
|
868
937
|
/**
|
|
@@ -913,51 +982,52 @@ function getHeaderPathQueryParamValue(use, param, fromSelf) {
|
|
|
913
982
|
return `${param}.unix_timestamp().to_string()`;
|
|
914
983
|
}
|
|
915
984
|
};
|
|
985
|
+
const paramType = helpers.unwrapType(param.type);
|
|
916
986
|
if (param.kind === 'headerCollection' || param.kind === 'queryCollection') {
|
|
917
987
|
if (param.format === 'multi') {
|
|
918
|
-
throw new
|
|
988
|
+
throw new CodegenError('InternalError', 'multi should have been handled outside getHeaderPathQueryParamValue');
|
|
919
989
|
}
|
|
920
|
-
else if (
|
|
990
|
+
else if (paramType.kind === 'String' || paramType.kind === 'str') {
|
|
921
991
|
return `${paramName}.join("${getCollectionDelimiter(param.format)}")`;
|
|
922
992
|
}
|
|
923
993
|
// convert the items to strings
|
|
924
994
|
let strConv;
|
|
925
|
-
switch (
|
|
995
|
+
switch (paramType.kind) {
|
|
926
996
|
case 'encodedBytes':
|
|
927
|
-
strConv = encodeBytes(
|
|
997
|
+
strConv = encodeBytes(paramType);
|
|
928
998
|
break;
|
|
929
999
|
case 'offsetDateTime':
|
|
930
|
-
strConv = `|i| ${encodeDateTime(
|
|
1000
|
+
strConv = `|i| ${encodeDateTime(paramType, 'i')}`;
|
|
931
1001
|
break;
|
|
932
1002
|
default:
|
|
933
1003
|
strConv = '|i| i.to_string()';
|
|
934
1004
|
}
|
|
935
1005
|
return `${param.name}.iter().map(${strConv}).collect::<Vec<String>>().join("${getCollectionDelimiter(param.format)}")`;
|
|
936
1006
|
}
|
|
937
|
-
switch (
|
|
1007
|
+
switch (paramType.kind) {
|
|
938
1008
|
case 'String':
|
|
939
1009
|
case 'str':
|
|
940
1010
|
return paramName;
|
|
1011
|
+
case 'decimal':
|
|
1012
|
+
return `${param.name}.to_string()`;
|
|
941
1013
|
case 'encodedBytes':
|
|
942
|
-
return encodeBytes(
|
|
1014
|
+
return encodeBytes(paramType, paramName);
|
|
943
1015
|
case 'enum':
|
|
944
1016
|
case 'scalar':
|
|
945
|
-
if (
|
|
1017
|
+
if (paramType.kind === 'enum' && param.kind === 'query') {
|
|
946
1018
|
// append_pair wants a reference to the string
|
|
947
1019
|
// TODO: https://github.com/Azure/typespec-rust/issues/25
|
|
948
1020
|
return `${paramName}.as_ref()`;
|
|
949
1021
|
}
|
|
950
1022
|
return `${paramName}.to_string()`;
|
|
951
1023
|
case 'enumValue':
|
|
952
|
-
return `${
|
|
953
|
-
case 'implTrait':
|
|
954
|
-
return `${paramName}.into()`;
|
|
1024
|
+
return `${paramType.type.name}::${paramType.name}.to_string()`;
|
|
955
1025
|
case 'literal':
|
|
956
|
-
return `"${
|
|
1026
|
+
return `"${paramType.value}"`;
|
|
957
1027
|
case 'offsetDateTime':
|
|
958
|
-
return encodeDateTime(
|
|
1028
|
+
return encodeDateTime(paramType, param.name);
|
|
959
1029
|
default:
|
|
960
|
-
throw new
|
|
1030
|
+
throw new CodegenError('InternalError', `unhandled ${param.kind} param type kind ${paramType.kind}`);
|
|
961
1031
|
}
|
|
962
1032
|
}
|
|
963
1033
|
/**
|