@azure-tools/typespec-rust 0.34.0 → 0.36.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.
Files changed (38) hide show
  1. package/dist/src/codegen/clients.js +13 -5
  2. package/dist/src/codegen/clients.js.map +1 -1
  3. package/dist/src/codegen/context.d.ts.map +1 -1
  4. package/dist/src/codegen/context.js +1 -2
  5. package/dist/src/codegen/context.js.map +1 -1
  6. package/dist/src/codegen/docTests.d.ts.map +1 -1
  7. package/dist/src/codegen/docTests.js +1 -2
  8. package/dist/src/codegen/docTests.js.map +1 -1
  9. package/dist/src/codegen/headerTraits.js +1 -0
  10. package/dist/src/codegen/headerTraits.js.map +1 -1
  11. package/dist/src/codegen/helpers.js +1 -1
  12. package/dist/src/codegen/mod.js +1 -1
  13. package/dist/src/codegen/mod.js.map +1 -1
  14. package/dist/src/codegen/models.js +42 -10
  15. package/dist/src/codegen/models.js.map +1 -1
  16. package/dist/src/codemodel/client.d.ts +7 -5
  17. package/dist/src/codemodel/client.d.ts.map +1 -1
  18. package/dist/src/codemodel/client.js +1 -1
  19. package/dist/src/codemodel/client.js.map +1 -1
  20. package/dist/src/codemodel/customizations.d.ts +12 -0
  21. package/dist/src/codemodel/customizations.d.ts.map +1 -0
  22. package/dist/src/codemodel/customizations.js +13 -0
  23. package/dist/src/codemodel/customizations.js.map +1 -0
  24. package/dist/src/codemodel/index.d.ts +1 -0
  25. package/dist/src/codemodel/index.d.ts.map +1 -1
  26. package/dist/src/codemodel/index.js +1 -0
  27. package/dist/src/codemodel/index.js.map +1 -1
  28. package/dist/src/codemodel/types.d.ts +3 -0
  29. package/dist/src/codemodel/types.d.ts.map +1 -1
  30. package/dist/src/codemodel/types.js +1 -0
  31. package/dist/src/codemodel/types.js.map +1 -1
  32. package/dist/src/emitter.js +1 -1
  33. package/dist/src/emitter.js.map +1 -1
  34. package/dist/src/tcgcadapter/adapter.d.ts +11 -3
  35. package/dist/src/tcgcadapter/adapter.d.ts.map +1 -1
  36. package/dist/src/tcgcadapter/adapter.js +137 -81
  37. package/dist/src/tcgcadapter/adapter.js.map +1 -1
  38. package/package.json +16 -16
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
- // cspell: ignore addl responseheader subclients lropaging
5
+ // cspell: ignore addl requiredness responseheader subclients lropaging
6
6
  import * as tsp from '@typespec/compiler';
7
7
  import * as helpers from './helpers.js';
8
8
  import * as naming from './naming.js';
@@ -10,6 +10,7 @@ import * as utils from '../utils/utils.js';
10
10
  import * as tcgc from '@azure-tools/typespec-client-generator-core';
11
11
  import * as rust from '../codemodel/index.js';
12
12
  import { FinalStateValue } from "@azure-tools/typespec-azure-core";
13
+ import { NoTarget } from "@typespec/compiler";
13
14
  /**
14
15
  * AdapterError is thrown when the emitter fails to convert part of the tcgc code
15
16
  * model to the emitter code model. this could be due to the emitter not supporting
@@ -69,8 +70,8 @@ export class Adapter {
69
70
  this.crate = new rust.Crate(this.options['crate-name'], this.options['crate-version'], serviceType);
70
71
  }
71
72
  /** performs all the steps to convert tcgc to a crate */
72
- tcgcToCrate() {
73
- this.adaptTypes();
73
+ tcgcToCrate(context) {
74
+ this.adaptTypes(context);
74
75
  this.adaptClients();
75
76
  // marker models don't require serde so exclude them from the check
76
77
  if (this.crate.enums.length > 0 || this.crate.models.some(e => e.kind === 'model')) {
@@ -96,11 +97,17 @@ export class Adapter {
96
97
  };
97
98
  }
98
99
  /** converts all tcgc types to their Rust type equivalent */
99
- adaptTypes() {
100
- var _a;
100
+ adaptTypes(context) {
101
101
  for (const sdkUnion of this.ctx.sdkPackage.unions.filter(u => u.kind === 'union')) {
102
102
  if (!sdkUnion.discriminatedOptions) {
103
- throw new AdapterError('UnsupportedTsp', 'non-discriminated unions are not supported', (_a = sdkUnion.__raw) === null || _a === void 0 ? void 0 : _a.node);
103
+ // When https://github.com/microsoft/typespec/issues/9749 is fixed, we can return to throwing an exception here.
104
+ context.program.reportDiagnostic({
105
+ code: 'UnsupportedTsp',
106
+ severity: 'warning',
107
+ message: `Non-discriminated unions ('${sdkUnion.name}') are not supported. No type will be generated.`,
108
+ target: NoTarget,
109
+ });
110
+ continue;
104
111
  }
105
112
  const rustUnion = this.getDiscriminatedUnion(sdkUnion);
106
113
  this.crate.unions.push(rustUnion);
@@ -486,7 +493,7 @@ export class Adapter {
486
493
  * @returns a Rust model field
487
494
  */
488
495
  getModelField(modelFlags, property, modelVisibility, stack) {
489
- var _a;
496
+ var _a, _b, _c, _d, _e;
490
497
  const fieldNeedsBoxing = function (fieldType) {
491
498
  if (fieldType.kind === 'model' && stack.includes(fieldType)) {
492
499
  // if the field's type is a model and it's in the type stack then
@@ -555,6 +562,34 @@ export class Adapter {
555
562
  else if (property.kind === 'property' && property.discriminator) {
556
563
  modelField.flags |= rust.ModelFieldFlags.Discriminator;
557
564
  }
565
+ // check for any client options on the field
566
+ const clientOptions = property.decorators.filter((decorator) => decorator.name === 'Azure.ClientGenerator.Core.@clientOption');
567
+ for (const clientOption of clientOptions) {
568
+ const optionName = clientOption.arguments['name'];
569
+ const optionValue = clientOption.arguments['value'];
570
+ switch (optionName) {
571
+ case 'deserialize_with':
572
+ if (modelField.customizations.find((each) => each.kind === 'deserializeWith')) {
573
+ // ignore any duplicates and warn about it
574
+ this.ctx.program.reportDiagnostic({
575
+ code: 'DuplicateClientOption',
576
+ severity: 'warning',
577
+ message: `duplicate client option ${optionName} on model field ${property.name} will be ignored`,
578
+ target: (_c = (_b = property.__raw) === null || _b === void 0 ? void 0 : _b.node) !== null && _c !== void 0 ? _c : tsp.NoTarget,
579
+ });
580
+ continue;
581
+ }
582
+ modelField.customizations.push(new rust.DeserializeWith(optionValue));
583
+ break;
584
+ default:
585
+ this.ctx.program.reportDiagnostic({
586
+ code: 'InvalidClientOption',
587
+ severity: 'warning',
588
+ message: `invalid client option ${optionName} on model field ${property.name}`,
589
+ target: (_e = (_d = property.__raw) === null || _d === void 0 ? void 0 : _d.node) !== null && _e !== void 0 ? _e : tsp.NoTarget,
590
+ });
591
+ }
592
+ }
558
593
  return modelField;
559
594
  }
560
595
  /**
@@ -652,19 +687,11 @@ export class Adapter {
652
687
  case 'plainDate':
653
688
  case 'plainTime':
654
689
  case 'string':
655
- case 'url': {
690
+ case 'url':
656
691
  if (type.kind === 'string' && type.crossLanguageDefinitionId === 'Azure.Core.eTag') {
657
- const etagKey = 'Etag';
658
- let etagType = this.types.get(etagKey);
659
- if (etagType) {
660
- return etagType;
661
- }
662
- etagType = new rust.Etag(this.crate);
663
- this.types.set(etagKey, etagType);
664
- return etagType;
692
+ return this.getEtag();
665
693
  }
666
694
  return this.getStringType();
667
- }
668
695
  case 'nullable':
669
696
  if (type.type.kind === 'model' && type.type.isGeneratedName) {
670
697
  // if the nullable type's target type is a synthesized
@@ -737,6 +764,17 @@ export class Adapter {
737
764
  this.types.set(keyName, encodedBytesType);
738
765
  return encodedBytesType;
739
766
  }
767
+ /** returns a Etag type */
768
+ getEtag() {
769
+ const etagKey = 'Etag';
770
+ let etagType = this.types.get(etagKey);
771
+ if (etagType) {
772
+ return etagType;
773
+ }
774
+ etagType = new rust.Etag(this.crate);
775
+ this.types.set(etagKey, etagType);
776
+ return etagType;
777
+ }
740
778
  /** returns a HashMap<String, type> */
741
779
  getHashMap(type) {
742
780
  const keyName = recursiveKeyName('hashmap', type);
@@ -924,10 +962,7 @@ export class Adapter {
924
962
  /** converts all tcgc clients and their methods into Rust clients/methods */
925
963
  adaptClients() {
926
964
  for (const client of this.ctx.sdkPackage.clients) {
927
- // start with instantiable clients and recursively work down
928
- if (client.clientInitialization.initializedBy & tcgc.InitializedByFlags.Individually) {
929
- this.recursiveAdaptClient(client);
930
- }
965
+ this.recursiveAdaptClient(client);
931
966
  }
932
967
  }
933
968
  /**
@@ -981,16 +1016,22 @@ export class Adapter {
981
1016
  rustClient.docs = this.adaptDocs(client.summary, client.doc);
982
1017
  rustClient.parent = parent;
983
1018
  rustClient.fields.push(new rust.StructField('pipeline', 'pubCrate', new rust.ExternalType(this.crate, 'Pipeline', 'azure_core::http')));
984
- // anything other than public means non-instantiable client
985
- if (client.clientInitialization.initializedBy & tcgc.InitializedByFlags.Individually) {
1019
+ // InitializedByFlags.CustomizeCode means the client is instantiable
1020
+ // but the constructor is to be omitted (i.e. hand-written).
1021
+ if (client.clientInitialization.initializedBy === tcgc.InitializedByFlags.CustomizeCode || client.clientInitialization.initializedBy & tcgc.InitializedByFlags.Individually) {
986
1022
  const clientOptionsStruct = new rust.Struct(`${rustClient.name}Options`, 'pub');
987
1023
  const clientOptionsField = new rust.StructField('client_options', 'pub', new rust.ExternalType(this.crate, 'ClientOptions', 'azure_core::http'));
988
1024
  clientOptionsField.docs.summary = 'Allows customization of the client.';
989
1025
  clientOptionsField.defaultValue = 'ClientOptions::default()';
990
1026
  clientOptionsStruct.fields.push(clientOptionsField);
991
1027
  rustClient.constructable = new rust.ClientConstruction(new rust.ClientOptions(clientOptionsStruct));
992
- rustClient.constructable.suppressed = this.options['omit-constructors'];
993
1028
  clientOptionsStruct.docs.summary = `Options used when creating a ${this.asDocLink(rustClient.name, rustClient.name)}`;
1029
+ if (this.options['omit-constructors']) {
1030
+ rustClient.constructable.suppressed = 'yes';
1031
+ }
1032
+ else if (client.clientInitialization.initializedBy === tcgc.InitializedByFlags.CustomizeCode) {
1033
+ rustClient.constructable.suppressed = 'ctor';
1034
+ }
994
1035
  // NOTE: per tcgc convention, if there is no param of kind credential
995
1036
  // it means that the client doesn't require any kind of authentication.
996
1037
  // HOWEVER, if there *is* a credential param, then the client *does not*
@@ -1108,6 +1149,11 @@ export class Adapter {
1108
1149
  break;
1109
1150
  }
1110
1151
  case 'method': {
1152
+ // https://github.com/Azure/typespec-rust/issues/849
1153
+ // Azure doesn't use optional (with no explicit default value) API versions anyway.
1154
+ if (param.isApiVersionParam && param.optional && !param.clientDefaultValue) {
1155
+ param.optional = false;
1156
+ }
1111
1157
  const clientParam = this.adaptClientParameter(param, rustClient.constructable);
1112
1158
  rustClient.fields.push(new rust.StructField(clientParam.name, 'pubCrate', clientParam.type));
1113
1159
  ctorParams.push(clientParam);
@@ -1401,7 +1447,7 @@ export class Adapter {
1401
1447
  adaptedParam = this.adaptMethodSpreadParameter(param, this.adaptPayloadFormat(opParam.defaultContentType), opParam.type);
1402
1448
  }
1403
1449
  else {
1404
- adaptedParam = this.adaptMethodParameter(opParam);
1450
+ adaptedParam = this.adaptMethodParameter(opParam, param);
1405
1451
  }
1406
1452
  switch (adaptedParam.kind) {
1407
1453
  case 'headerScalar':
@@ -1688,7 +1734,8 @@ export class Adapter {
1688
1734
  responseHeader = new rust.ResponseHeaderHashMap(utils.snakeCaseName(header.name), lowerCasedHeader);
1689
1735
  }
1690
1736
  else {
1691
- responseHeader = new rust.ResponseHeaderScalar(utils.snakeCaseName(header.name), utils.fixETagName(lowerCasedHeader), this.typeToWireType(this.getType(header.type)));
1737
+ const headerType = lowerCasedHeader.match(/^etag$/) ? this.getEtag() : this.typeToWireType(this.getType(header.type));
1738
+ responseHeader = new rust.ResponseHeaderScalar(utils.snakeCaseName(header.name), utils.fixETagName(lowerCasedHeader), headerType);
1692
1739
  }
1693
1740
  responseHeader.docs = this.adaptDocs(header.summary, header.doc);
1694
1741
  responseHeadersMap.set(header, responseHeader);
@@ -1735,14 +1782,6 @@ export class Adapter {
1735
1782
  return utils.capitalize(type.kind);
1736
1783
  }
1737
1784
  };
1738
- const throwOnUnitType = function (type) {
1739
- if (type.kind === 'unit') {
1740
- // this is to filter out unit from ResponseTypes.
1741
- // methods that return unit should have been skipped by our caller
1742
- // so we should never hit this (if we do, we have a bug elsewhere).
1743
- throw new AdapterError('InternalError', `unexpected trait impl kind ${type.kind}`);
1744
- }
1745
- };
1746
1785
  // response header traits are only ever for marker types and payloads
1747
1786
  let implFor;
1748
1787
  switch (method.returns.type.kind) {
@@ -1751,12 +1790,23 @@ export class Adapter {
1751
1790
  implFor = method.returns.type.type;
1752
1791
  break;
1753
1792
  case 'response':
1754
- throwOnUnitType(method.returns.type.content);
1755
- implFor = method.returns.type;
1793
+ switch (method.returns.type.content.kind) {
1794
+ case 'marker':
1795
+ case 'model':
1796
+ implFor = method.returns.type;
1797
+ break;
1798
+ default:
1799
+ throw new AdapterError('InternalError', `unexpected trait impl content kind ${method.returns.type.content.kind}`);
1800
+ }
1756
1801
  break;
1757
1802
  case 'asyncResponse':
1758
- throwOnUnitType(method.returns.type.type);
1759
- implFor = method.returns.type;
1803
+ switch (method.returns.type.type.kind) {
1804
+ case 'marker':
1805
+ implFor = method.returns.type;
1806
+ break;
1807
+ default:
1808
+ throw new AdapterError('InternalError', `unexpected trait impl type kind ${method.returns.type.type.kind}`);
1809
+ }
1760
1810
  break;
1761
1811
  }
1762
1812
  const traitName = `${recursiveTypeName(implFor.kind === 'asyncResponse' ? implFor.type : implFor.content)}Headers`;
@@ -1882,12 +1932,17 @@ export class Adapter {
1882
1932
  return paramsForReinjection;
1883
1933
  }
1884
1934
  /**
1885
- * converts a tcgc operation parameter into a Rust method parameter
1935
+ * converts a tcgc operation parameter into a Rust method parameter.
1936
+ * note that when methodParam is present, we must use all applicable
1937
+ * values from methodParam as the source of truth. e.g. when overriding
1938
+ * a method to make an optional param required, the requiredness will
1939
+ * be reflected in the method param, _not_ the operation param.
1886
1940
  *
1887
- * @param param the tcgc operation parameter to convert
1941
+ * @param opParam the tcgc operation parameter to convert
1942
+ * @param methodParam the tcgc method parameter associated with opParam
1888
1943
  * @returns a Rust method parameter
1889
1944
  */
1890
- adaptMethodParameter(param) {
1945
+ adaptMethodParameter(opParam, methodParam) {
1891
1946
  var _a, _b, _c, _d, _e, _f, _g, _h;
1892
1947
  /**
1893
1948
  * used to create keys for this.clientMethodParams
@@ -1899,10 +1954,10 @@ export class Adapter {
1899
1954
  // in different places across methods (path/query)
1900
1955
  return `${param.name}-${param.kind}`;
1901
1956
  };
1902
- const paramLoc = param.onClient ? 'client' : 'method';
1957
+ const paramLoc = opParam.onClient ? 'client' : 'method';
1903
1958
  // if this is a client method param, check if we've already adapted it
1904
1959
  if (paramLoc === 'client') {
1905
- const clientMethodParam = this.clientMethodParams.get(getClientParamsKey(param));
1960
+ const clientMethodParam = this.clientMethodParams.get(getClientParamsKey(opParam));
1906
1961
  if (clientMethodParam) {
1907
1962
  return clientMethodParam;
1908
1963
  }
@@ -1918,40 +1973,41 @@ export class Adapter {
1918
1973
  }
1919
1974
  return param.name;
1920
1975
  };
1921
- const paramName = naming.getEscapedReservedName(utils.snakeCaseName(getCorrespondingClientParamName(param)), 'param', reservedParams);
1922
- let paramType = this.getType(param.type);
1976
+ const paramName = naming.getEscapedReservedName(utils.snakeCaseName(getCorrespondingClientParamName(opParam)), 'param', reservedParams);
1977
+ const paramOptional = methodParam ? methodParam.optional : opParam.optional;
1978
+ let paramType = this.getType(methodParam ? methodParam.type : opParam.type);
1923
1979
  // for required header/path/query method string params, we might emit them as borrowed types
1924
- if (!param.optional && !param.onClient && (param.kind === 'header' || param.kind === 'path' || param.kind === 'query')) {
1925
- const borrowedType = this.canBorrowMethodParam(paramType, param.kind);
1980
+ if (!paramOptional && paramLoc !== 'client' && (opParam.kind === 'header' || opParam.kind === 'path' || opParam.kind === 'query')) {
1981
+ const borrowedType = this.canBorrowMethodParam(paramType, opParam.kind);
1926
1982
  if (borrowedType) {
1927
1983
  paramType = borrowedType;
1928
1984
  }
1929
1985
  }
1930
1986
  let adaptedParam;
1931
- switch (param.kind) {
1987
+ switch (opParam.kind) {
1932
1988
  case 'body': {
1933
1989
  let requestType;
1934
- if (param.type.kind === 'bytes' && param.type.encode === 'bytes') {
1990
+ if (opParam.type.kind === 'bytes' && opParam.type.encode === 'bytes') {
1935
1991
  // bytes encoding indicates a streaming binary request
1936
1992
  requestType = new rust.Bytes(this.crate);
1937
1993
  }
1938
1994
  else {
1939
- requestType = new rust.Payload(this.typeToWireType(paramType), this.adaptPayloadFormat(param.defaultContentType));
1995
+ requestType = new rust.Payload(this.typeToWireType(paramType), this.adaptPayloadFormat(opParam.defaultContentType));
1940
1996
  }
1941
- const requestFormatType = this.adaptPayloadFormatType(param.defaultContentType);
1942
- adaptedParam = new rust.BodyParameter(paramName, paramLoc, param.optional, new rust.RequestContent(this.crate, requestType, requestFormatType));
1997
+ const requestFormatType = this.adaptPayloadFormatType(opParam.defaultContentType);
1998
+ adaptedParam = new rust.BodyParameter(paramName, paramLoc, paramOptional, new rust.RequestContent(this.crate, requestType, requestFormatType));
1943
1999
  break;
1944
2000
  }
1945
2001
  case 'cookie':
1946
2002
  // TODO: https://github.com/Azure/typespec-rust/issues/192
1947
- throw new AdapterError('UnsupportedTsp', 'cookie parameters are not supported', (_a = param.__raw) === null || _a === void 0 ? void 0 : _a.node);
2003
+ throw new AdapterError('UnsupportedTsp', 'cookie parameters are not supported', (_a = opParam.__raw) === null || _a === void 0 ? void 0 : _a.node);
1948
2004
  case 'header':
1949
- if (param.collectionFormat) {
2005
+ if (opParam.collectionFormat) {
1950
2006
  if (paramType.kind !== 'Vec' && !isRefSlice(paramType)) {
1951
- throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for HeaderCollectionParameter`, (_b = param.__raw) === null || _b === void 0 ? void 0 : _b.node);
2007
+ throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for HeaderCollectionParameter`, (_b = opParam.__raw) === null || _b === void 0 ? void 0 : _b.node);
1952
2008
  }
1953
2009
  let format;
1954
- switch (param.collectionFormat) {
2010
+ switch (opParam.collectionFormat) {
1955
2011
  case 'csv':
1956
2012
  case 'simple':
1957
2013
  format = 'csv';
@@ -1959,18 +2015,18 @@ export class Adapter {
1959
2015
  case 'pipes':
1960
2016
  case 'ssv':
1961
2017
  case 'tsv':
1962
- format = param.collectionFormat;
2018
+ format = opParam.collectionFormat;
1963
2019
  break;
1964
2020
  default:
1965
- throw new AdapterError('InternalError', `unexpected format ${param.collectionFormat} for HeaderCollectionParameter`, (_c = param.__raw) === null || _c === void 0 ? void 0 : _c.node);
2021
+ throw new AdapterError('InternalError', `unexpected format ${opParam.collectionFormat} for HeaderCollectionParameter`, (_c = opParam.__raw) === null || _c === void 0 ? void 0 : _c.node);
1966
2022
  }
1967
- adaptedParam = new rust.HeaderCollectionParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, format);
2023
+ adaptedParam = new rust.HeaderCollectionParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, format);
1968
2024
  }
1969
- else if (param.serializedName === 'x-ms-meta') {
2025
+ else if (opParam.serializedName === 'x-ms-meta') {
1970
2026
  if (paramType.kind !== 'hashmap' && !isRefHashMap(paramType)) {
1971
- throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for header ${param.serializedName}`, (_d = param.__raw) === null || _d === void 0 ? void 0 : _d.node);
2027
+ throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for header ${opParam.serializedName}`, (_d = opParam.__raw) === null || _d === void 0 ? void 0 : _d.node);
1972
2028
  }
1973
- adaptedParam = new rust.HeaderHashMapParameter(paramName, param.serializedName, paramLoc, param.optional, paramType);
2029
+ adaptedParam = new rust.HeaderHashMapParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType);
1974
2030
  }
1975
2031
  else {
1976
2032
  paramType = this.typeToWireType(paramType);
@@ -1981,28 +2037,28 @@ export class Adapter {
1981
2037
  case 'slice':
1982
2038
  case 'str':
1983
2039
  case 'Vec':
1984
- throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for scalar header ${param.serializedName}`, (_e = param.__raw) === null || _e === void 0 ? void 0 : _e.node);
2040
+ throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for scalar header ${opParam.serializedName}`, (_e = opParam.__raw) === null || _e === void 0 ? void 0 : _e.node);
1985
2041
  }
1986
- adaptedParam = new rust.HeaderScalarParameter(paramName, param.serializedName, paramLoc, param.optional, paramType);
1987
- adaptedParam.isApiVersion = param.isApiVersionParam;
2042
+ adaptedParam = new rust.HeaderScalarParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType);
2043
+ adaptedParam.isApiVersion = opParam.isApiVersionParam;
1988
2044
  }
1989
2045
  break;
1990
2046
  case 'path':
1991
2047
  {
1992
2048
  paramType = this.typeToWireType(paramType);
1993
2049
  let style = 'simple';
1994
- const tspStyleString = param.style;
2050
+ const tspStyleString = opParam.style;
1995
2051
  if (!['simple', 'path', 'label', 'matrix'].includes(tspStyleString)) {
1996
- throw new AdapterError('InternalError', `unsupported style ${tspStyleString} for parameter ${param.serializedName}`, (_f = param.__raw) === null || _f === void 0 ? void 0 : _f.node);
2052
+ throw new AdapterError('InternalError', `unsupported style ${tspStyleString} for parameter ${opParam.serializedName}`, (_f = opParam.__raw) === null || _f === void 0 ? void 0 : _f.node);
1997
2053
  }
1998
2054
  else {
1999
2055
  style = tspStyleString;
2000
2056
  }
2001
2057
  if (isRefSlice(paramType)) {
2002
- adaptedParam = new rust.PathCollectionParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, param.allowReserved, style, param.explode);
2058
+ adaptedParam = new rust.PathCollectionParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, opParam.allowReserved, style, opParam.explode);
2003
2059
  }
2004
2060
  else if (paramType.kind === 'hashmap' || isRefHashMap(paramType)) {
2005
- adaptedParam = new rust.PathHashMapParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, param.allowReserved, style, param.explode);
2061
+ adaptedParam = new rust.PathHashMapParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, opParam.allowReserved, style, opParam.explode);
2006
2062
  }
2007
2063
  else {
2008
2064
  switch (paramType.kind) {
@@ -2011,25 +2067,25 @@ export class Adapter {
2011
2067
  case 'slice':
2012
2068
  case 'str':
2013
2069
  case 'Vec':
2014
- throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for scalar path ${param.serializedName}`, (_g = param.__raw) === null || _g === void 0 ? void 0 : _g.node);
2070
+ throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for scalar path ${opParam.serializedName}`, (_g = opParam.__raw) === null || _g === void 0 ? void 0 : _g.node);
2015
2071
  }
2016
- adaptedParam = new rust.PathScalarParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, param.allowReserved, style);
2072
+ adaptedParam = new rust.PathScalarParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, opParam.allowReserved, style);
2017
2073
  }
2018
2074
  }
2019
2075
  break;
2020
2076
  case 'query':
2021
2077
  paramType = this.typeToWireType(paramType);
2022
2078
  if (paramType.kind === 'Vec' || isRefSlice(paramType)) {
2023
- let format = param.explode ? 'multi' : 'csv';
2024
- if (param.collectionFormat) {
2025
- format = param.collectionFormat === 'simple' ? 'csv' : (param.collectionFormat === 'form' ? 'multi' : param.collectionFormat);
2079
+ let format = opParam.explode ? 'multi' : 'csv';
2080
+ if (opParam.collectionFormat) {
2081
+ format = opParam.collectionFormat === 'simple' ? 'csv' : (opParam.collectionFormat === 'form' ? 'multi' : opParam.collectionFormat);
2026
2082
  }
2027
2083
  // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
2028
- adaptedParam = new rust.QueryCollectionParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, true, format);
2084
+ adaptedParam = new rust.QueryCollectionParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, true, format);
2029
2085
  }
2030
2086
  else if (paramType.kind === 'hashmap' || isRefHashMap(paramType)) {
2031
2087
  // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
2032
- adaptedParam = new rust.QueryHashMapParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, true, param.explode);
2088
+ adaptedParam = new rust.QueryHashMapParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, true, opParam.explode);
2033
2089
  }
2034
2090
  else {
2035
2091
  switch (paramType.kind) {
@@ -2037,17 +2093,17 @@ export class Adapter {
2037
2093
  case 'model':
2038
2094
  case 'slice':
2039
2095
  case 'str':
2040
- throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for scalar query ${param.serializedName}`, (_h = param.__raw) === null || _h === void 0 ? void 0 : _h.node);
2096
+ throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for scalar query ${opParam.serializedName}`, (_h = opParam.__raw) === null || _h === void 0 ? void 0 : _h.node);
2041
2097
  }
2042
2098
  // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
2043
- adaptedParam = new rust.QueryScalarParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, true);
2044
- adaptedParam.isApiVersion = param.isApiVersionParam;
2099
+ adaptedParam = new rust.QueryScalarParameter(paramName, opParam.serializedName, paramLoc, paramOptional, paramType, true);
2100
+ adaptedParam.isApiVersion = opParam.isApiVersionParam;
2045
2101
  }
2046
2102
  break;
2047
2103
  }
2048
- adaptedParam.docs = this.adaptDocs(param.summary, param.doc);
2104
+ adaptedParam.docs = this.adaptDocs(methodParam ? methodParam.summary : opParam.summary, methodParam ? methodParam.doc : opParam.doc);
2049
2105
  if (paramLoc === 'client') {
2050
- this.clientMethodParams.set(getClientParamsKey(param), adaptedParam);
2106
+ this.clientMethodParams.set(getClientParamsKey(opParam), adaptedParam);
2051
2107
  }
2052
2108
  return adaptedParam;
2053
2109
  }