@azure-tools/typespec-rust 0.24.1 → 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.
Files changed (34) hide show
  1. package/dist/src/codegen/clients.d.ts.map +1 -1
  2. package/dist/src/codegen/clients.js +184 -117
  3. package/dist/src/codegen/clients.js.map +1 -1
  4. package/dist/src/codegen/context.d.ts.map +1 -1
  5. package/dist/src/codegen/context.js +3 -1
  6. package/dist/src/codegen/context.js.map +1 -1
  7. package/dist/src/codegen/enums.d.ts +2 -2
  8. package/dist/src/codegen/enums.js +57 -22
  9. package/dist/src/codegen/enums.js.map +1 -1
  10. package/dist/src/codegen/helpers.d.ts +10 -0
  11. package/dist/src/codegen/helpers.d.ts.map +1 -1
  12. package/dist/src/codegen/helpers.js +29 -3
  13. package/dist/src/codegen/helpers.js.map +1 -1
  14. package/dist/src/codegen/models.js +6 -5
  15. package/dist/src/codegen/models.js.map +1 -1
  16. package/dist/src/codemodel/client.d.ts +10 -8
  17. package/dist/src/codemodel/client.d.ts.map +1 -1
  18. package/dist/src/codemodel/client.js +1 -0
  19. package/dist/src/codemodel/client.js.map +1 -1
  20. package/dist/src/codemodel/crate.d.ts.map +1 -1
  21. package/dist/src/codemodel/crate.js +5 -2
  22. package/dist/src/codemodel/crate.js.map +1 -1
  23. package/dist/src/codemodel/types.d.ts +2 -11
  24. package/dist/src/codemodel/types.d.ts.map +1 -1
  25. package/dist/src/codemodel/types.js +0 -7
  26. package/dist/src/codemodel/types.js.map +1 -1
  27. package/dist/src/shared/shared.d.ts.map +1 -1
  28. package/dist/src/shared/shared.js +4 -1
  29. package/dist/src/shared/shared.js.map +1 -1
  30. package/dist/src/tcgcadapter/adapter.d.ts +9 -1
  31. package/dist/src/tcgcadapter/adapter.d.ts.map +1 -1
  32. package/dist/src/tcgcadapter/adapter.js +111 -72
  33. package/dist/src/tcgcadapter/adapter.js.map +1 -1
  34. package/package.json +8 -8
@@ -60,7 +60,6 @@ export class Adapter {
60
60
  constructor(ctx, options) {
61
61
  this.types = new Map();
62
62
  this.clientMethodParams = new Map();
63
- this.renamedMethods = new Set();
64
63
  this.fieldsMap = new Map();
65
64
  this.ctx = ctx;
66
65
  this.options = options;
@@ -133,7 +132,7 @@ export class Adapter {
133
132
  */
134
133
  getEnum(sdkEnum) {
135
134
  var _a;
136
- const enumName = codegen.capitalize(sdkEnum.name);
135
+ const enumName = codegen.deconstruct(sdkEnum.name).map((each) => codegen.capitalize(each)).join('');
137
136
  let rustEnum = this.types.get(enumName);
138
137
  if (rustEnum) {
139
138
  return rustEnum;
@@ -503,6 +502,11 @@ export class Adapter {
503
502
  return this.getStringType();
504
503
  }
505
504
  case 'nullable':
505
+ if (type.type.kind === 'model' && type.type.isGeneratedName) {
506
+ // if the nullable type's target type is a synthesized
507
+ // type, we need to propagate the docs to it
508
+ type.type.doc = type.doc;
509
+ }
506
510
  // TODO: workaround until https://github.com/Azure/typespec-rust/issues/42 is fixed
507
511
  return this.getType(type.type, stack);
508
512
  case 'offsetDateTime': {
@@ -780,7 +784,7 @@ export class Adapter {
780
784
  * @returns a Rust client
781
785
  */
782
786
  recursiveAdaptClient(client, parent) {
783
- var _a, _b, _c, _d, _e;
787
+ var _a, _b, _c, _d;
784
788
  let clientName = client.name;
785
789
  // NOTE: if the client has the @clientName decorator applied then use that verbatim
786
790
  if (parent && !hasClientNameDecorator(client.decorators)) {
@@ -826,30 +830,35 @@ export class Adapter {
826
830
  (function (AuthTypes) {
827
831
  AuthTypes[AuthTypes["Default"] = 0] = "Default";
828
832
  AuthTypes[AuthTypes["NoAuth"] = 1] = "NoAuth";
829
- AuthTypes[AuthTypes["WithAut"] = 2] = "WithAut";
833
+ AuthTypes[AuthTypes["WithAuth"] = 2] = "WithAuth";
830
834
  })(AuthTypes || (AuthTypes = {}));
831
835
  let authType = AuthTypes.Default;
832
836
  /**
833
837
  * processes a credential, potentially adding its supporting client constructor
834
838
  *
839
+ * @param rustClient the client for which the constructor will be added
840
+ * @param param the tsp parameter that contains cred
835
841
  * @param cred the credential type to process
836
842
  * @param constructable the constructable for the current Rust client
837
- * @param throwOnDefault when true, throws an error on unsupported credential types
838
843
  * @returns the AuthTypes enum for the credential that was handled, or AuthTypes.Default if none were
839
844
  */
840
- const processCredential = (rustClient, cred, constructable, throwOnDefault) => {
845
+ const processCredential = (rustClient, param, cred, constructable) => {
846
+ var _a, _b;
841
847
  switch (cred.type) {
842
848
  case 'noAuth':
843
849
  return AuthTypes.NoAuth;
844
850
  case 'oauth2': {
845
851
  constructable.constructors.push(this.createTokenCredentialCtor(rustClient, cred));
846
- return AuthTypes.WithAut;
852
+ return AuthTypes.WithAuth;
847
853
  }
848
854
  default:
849
- if (throwOnDefault) {
850
- throw new AdapterError('UnsupportedTsp', `credential scheme type ${cred.type} NYI`);
851
- }
852
- return AuthTypes.Default;
855
+ this.ctx.program.reportDiagnostic({
856
+ code: 'UnsupportedAuthenticationScheme',
857
+ severity: 'warning',
858
+ message: `authentication scheme ${cred.type} is not supported`,
859
+ target: (_b = (_a = param.__raw) === null || _a === void 0 ? void 0 : _a.node) !== null && _b !== void 0 ? _b : NoTarget,
860
+ });
861
+ return AuthTypes.WithAuth;
853
862
  }
854
863
  };
855
864
  const ctorParams = new Array();
@@ -858,7 +867,7 @@ export class Adapter {
858
867
  case 'credential':
859
868
  switch (param.type.kind) {
860
869
  case 'credential':
861
- authType |= processCredential(rustClient, param.type.scheme, rustClient.constructable, true);
870
+ authType |= processCredential(rustClient, param, param.type.scheme, rustClient.constructable);
862
871
  break;
863
872
  case 'union': {
864
873
  const variantKinds = new Array();
@@ -867,13 +876,8 @@ export class Adapter {
867
876
  // if OAuth2 is specified then emit that and skip any unsupported ones.
868
877
  // this prevents emitting the with_no_credential constructor in cases
869
878
  // where it might not actually be supported.
870
- authType |= processCredential(rustClient, variantType.scheme, rustClient.constructable, false);
871
- }
872
- // no supported credential types were specified
873
- if (authType === AuthTypes.Default) {
874
- throw new AdapterError('UnsupportedTsp', `credential scheme types ${variantKinds.join()} NYI`, (_a = param.__raw) === null || _a === void 0 ? void 0 : _a.node);
879
+ authType |= processCredential(rustClient, param, variantType.scheme, rustClient.constructable);
875
880
  }
876
- continue;
877
881
  }
878
882
  }
879
883
  break;
@@ -912,26 +916,16 @@ export class Adapter {
912
916
  // there's either a suffix on the endpoint param, more template arguments, or both.
913
917
  // either way we need to create supplemental info on the constructable.
914
918
  // NOTE: we remove the {endpoint} segment and trailing forward slash as we use
915
- // Url::join to concatenate the two and not string replacement.
916
- let serverUrl = endpointType.serverUrl.replace(`{${templateArg.serializedName}}/`, '');
917
- // NOTE: the behavior of Url::join requires that the path ends with a forward slash.
918
- // if there are any query params, splice it in as required else just append it.
919
- if (serverUrl.includes('?')) {
920
- if (serverUrl[serverUrl.indexOf('?') - 1] !== '/') {
921
- serverUrl = serverUrl.replace('?', '/?');
922
- }
923
- }
924
- else if (serverUrl[serverUrl.length - 1] !== '/') {
925
- serverUrl += '/';
926
- }
919
+ // UrlExt::append_path() to concatenate the two and not string replacement.
920
+ const serverUrl = endpointType.serverUrl.replace(`{${templateArg.serializedName}}/`, '');
927
921
  rustClient.constructable.endpoint = new rust.SupplementalEndpoint(serverUrl);
928
922
  continue;
929
923
  }
930
924
  const clientParam = this.adaptClientParameter(templateArg, rustClient.constructable);
931
925
  if (clientParam.kind !== 'clientSupplementalEndpoint') {
932
- throw new AdapterError('InternalError', `unexpected client parameter kind ${clientParam.kind}`, (_b = templateArg.__raw) === null || _b === void 0 ? void 0 : _b.node);
926
+ throw new AdapterError('InternalError', `unexpected client parameter kind ${clientParam.kind}`, (_a = templateArg.__raw) === null || _a === void 0 ? void 0 : _a.node);
933
927
  }
934
- (_c = rustClient.constructable.endpoint) === null || _c === void 0 ? void 0 : _c.parameters.push(clientParam);
928
+ (_b = rustClient.constructable.endpoint) === null || _b === void 0 ? void 0 : _b.parameters.push(clientParam);
935
929
  ctorParams.push(clientParam);
936
930
  }
937
931
  break;
@@ -991,7 +985,7 @@ export class Adapter {
991
985
  code: 'LroPagingNotSupported',
992
986
  severity: 'warning',
993
987
  message: `skip emitting Paging LRO ${method.name}`,
994
- target: (_e = (_d = method.__raw) === null || _d === void 0 ? void 0 : _d.node) !== null && _e !== void 0 ? _e : NoTarget,
988
+ target: (_d = (_c = method.__raw) === null || _c === void 0 ? void 0 : _c.node) !== null && _d !== void 0 ? _d : NoTarget,
995
989
  });
996
990
  continue;
997
991
  }
@@ -1112,13 +1106,17 @@ export class Adapter {
1112
1106
  * @param rustClient the client to which the method belongs
1113
1107
  */
1114
1108
  adaptMethod(method, rustClient) {
1115
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
1109
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
1116
1110
  let srcMethodName = method.name;
1117
1111
  if (method.kind === 'paging' && !srcMethodName.match(/^list/i)) {
1118
1112
  const chunks = codegen.deconstruct(srcMethodName);
1119
- chunks[0] = 'list';
1113
+ if (chunks[0] === 'get') {
1114
+ chunks[0] = 'list';
1115
+ }
1116
+ else {
1117
+ chunks.unshift('list');
1118
+ }
1120
1119
  srcMethodName = codegen.camelCase(chunks);
1121
- this.renamedMethods.add(srcMethodName);
1122
1120
  this.ctx.program.reportDiagnostic({
1123
1121
  code: 'PagingMethodRename',
1124
1122
  severity: 'warning',
@@ -1126,13 +1124,18 @@ export class Adapter {
1126
1124
  target: (_b = (_a = method.__raw) === null || _a === void 0 ? void 0 : _a.node) !== null && _b !== void 0 ? _b : NoTarget,
1127
1125
  });
1128
1126
  }
1129
- else if (this.renamedMethods.has(srcMethodName)) {
1130
- throw new AdapterError('NameCollision', `method name ${srcMethodName} collides with a renamed method`, (_c = method.__raw) === null || _c === void 0 ? void 0 : _c.node);
1131
- }
1132
1127
  const languageIndependentName = method.crossLanguageDefinitionId;
1133
1128
  const methodName = naming.getEscapedReservedName(snakeCaseName(srcMethodName), 'fn');
1129
+ if (srcMethodName !== method.name) {
1130
+ // if the method was renamed then ensure it doesn't collide
1131
+ for (const existingMethod of rustClient.methods) {
1132
+ if (existingMethod.name === methodName) {
1133
+ throw new AdapterError('NameCollision', `renamed method ${srcMethodName} collides with an existing method`, (_c = method.__raw) === null || _c === void 0 ? void 0 : _c.node);
1134
+ }
1135
+ }
1136
+ }
1134
1137
  const optionsLifetime = new rust.Lifetime('a');
1135
- const methodOptionsStruct = new rust.Struct(`${rustClient.name}${codegen.pascalCase(srcMethodName)}Options`, 'pub');
1138
+ const methodOptionsStruct = new rust.Struct(`${rustClient.name}${codegen.pascalCase(srcMethodName, false)}Options`, 'pub');
1136
1139
  methodOptionsStruct.lifetime = optionsLifetime;
1137
1140
  methodOptionsStruct.docs.summary = `Options to be passed to ${this.asDocLink(`${rustClient.name}::${methodName}()`, `crate::generated::clients::${rustClient.name}::${methodName}()`)}`;
1138
1141
  const clientMethodOptions = new rust.ExternalType(this.crate, 'ClientMethodOptions', 'azure_core::http');
@@ -1149,27 +1152,16 @@ export class Adapter {
1149
1152
  const pub = method.access === 'public' ? 'pub' : 'pubCrate';
1150
1153
  const methodOptions = new rust.MethodOptions(methodOptionsStruct);
1151
1154
  const httpMethod = method.operation.verb;
1152
- // if path is more than just "/" strip off any leading forward slash.
1153
- // this is because Url::join will treat the path as absolute, overwriting
1154
- // any existing path on the endpoint.
1155
- // e.g. if endpoint is https://contoso.com/foo/bar and httpPath is /some/sub/path
1156
- // then calling Url::join will provide result https://contoso.com/some/sub/path
1157
- // which is not what we want.
1158
- // the only exception is if this is the root before the query string
1159
- let httpPath = method.operation.path;
1160
- if (httpPath.length > 1 && httpPath[0] === '/' && !httpPath.startsWith('/?')) {
1161
- httpPath = httpPath.slice(1);
1162
- }
1163
1155
  let rustMethod;
1164
1156
  switch (method.kind) {
1165
1157
  case 'basic':
1166
- rustMethod = new rust.AsyncMethod(methodName, languageIndependentName, rustClient, pub, methodOptions, httpMethod, httpPath);
1158
+ rustMethod = new rust.AsyncMethod(methodName, languageIndependentName, rustClient, pub, methodOptions, httpMethod, method.operation.path);
1167
1159
  break;
1168
1160
  case 'paging':
1169
- rustMethod = new rust.PageableMethod(methodName, languageIndependentName, rustClient, pub, methodOptions, httpMethod, httpPath);
1161
+ rustMethod = new rust.PageableMethod(methodName, languageIndependentName, rustClient, pub, methodOptions, httpMethod, method.operation.path);
1170
1162
  break;
1171
1163
  case 'lro':
1172
- rustMethod = new rust.LroMethod(methodName, languageIndependentName, rustClient, pub, methodOptions, httpMethod, httpPath);
1164
+ rustMethod = new rust.LroMethod(methodName, languageIndependentName, rustClient, pub, methodOptions, httpMethod, method.operation.path);
1173
1165
  break;
1174
1166
  default:
1175
1167
  throw new AdapterError('UnsupportedTsp', `method kind ${method.kind} NYI`, (_d = method.__raw) === null || _d === void 0 ? void 0 : _d.node);
@@ -1381,14 +1373,8 @@ export class Adapter {
1381
1373
  if (unwrappedCount !== method.pagingMetadata.pageItemsSegments.length) {
1382
1374
  throw new AdapterError('InternalError', `failed to unwrap paged items for method ${method.name}`, (_m = method.__raw) === null || _m === void 0 ? void 0 : _m.node);
1383
1375
  }
1384
- // if the response contains more than the Vec<T> and next_link then use a PageIterator
1385
- if (synthesizedModel.fields.length > 2) {
1386
- rustMethod.returns = new rust.Result(this.crate, new rust.PageIterator(this.crate, new rust.Response(this.crate, synthesizedModel, responseFormat)));
1387
- }
1388
- else {
1389
- this.crate.addDependency(new rust.CrateDependency('async-trait'));
1390
- rustMethod.returns = new rust.Result(this.crate, new rust.Pager(this.crate, new rust.Response(this.crate, synthesizedModel, responseFormat)));
1391
- }
1376
+ this.crate.addDependency(new rust.CrateDependency('async-trait'));
1377
+ rustMethod.returns = new rust.Result(this.crate, new rust.Pager(this.crate, new rust.Response(this.crate, synthesizedModel, responseFormat)));
1392
1378
  }
1393
1379
  else if (method.kind === 'lro') {
1394
1380
  const format = responseFormat === 'NoFormat' ? 'JsonFormat' : responseFormat;
@@ -1420,7 +1406,7 @@ export class Adapter {
1420
1406
  else if (responseHeaders.length > 0) {
1421
1407
  // for methods that don't return a modeled type but return headers,
1422
1408
  // we need to return a marker type
1423
- const markerType = new rust.MarkerType(`${rustClient.name}${codegen.pascalCase(method.name)}Result`);
1409
+ const markerType = new rust.MarkerType(`${rustClient.name}${codegen.pascalCase(method.name, false)}Result`);
1424
1410
  markerType.docs.summary = `Contains results for ${this.asDocLink(`${rustClient.name}::${methodName}()`, `crate::generated::clients::${rustClient.name}::${methodName}()`)}`;
1425
1411
  this.crate.models.push(markerType);
1426
1412
  let resultType;
@@ -1453,7 +1439,11 @@ export class Adapter {
1453
1439
  rustMethod.responseHeaders = this.adaptResponseHeadersTrait(rustClient, rustMethod, Array.from(responseHeadersMap.values()));
1454
1440
  if (method.kind === 'paging') {
1455
1441
  // can't do this until the method has been completely adapted
1456
- rustMethod.strategy = this.adaptPageableMethodStrategy(method, paramsMap, responseHeadersMap);
1442
+ const pageableMethod = rustMethod;
1443
+ pageableMethod.strategy = this.adaptPageableMethodStrategy(method, paramsMap, responseHeadersMap);
1444
+ if (((_p = pageableMethod.strategy) === null || _p === void 0 ? void 0 : _p.kind) === 'nextLink') {
1445
+ pageableMethod.strategy.reinjectedParams = this.adaptPageableMethodReinjectionParams(method, paramsMap);
1446
+ }
1457
1447
  }
1458
1448
  }
1459
1449
  /**
@@ -1534,7 +1524,6 @@ export class Adapter {
1534
1524
  // response header traits are only ever for marker types and payloads
1535
1525
  let implFor;
1536
1526
  switch (method.returns.type.kind) {
1537
- case 'pageIterator':
1538
1527
  case 'pager':
1539
1528
  case 'poller':
1540
1529
  implFor = method.returns.type.type;
@@ -1564,7 +1553,7 @@ export class Adapter {
1564
1553
  * @returns the pageable strategy
1565
1554
  */
1566
1555
  adaptPageableMethodStrategy(method, paramsMap, respHeadersMap) {
1567
- var _a, _b, _c, _d, _e;
1556
+ var _a, _b, _c, _d, _e, _f;
1568
1557
  const buildNextLinkPath = (segments) => {
1569
1558
  var _a, _b;
1570
1559
  // build the field path for the next link segments
@@ -1600,11 +1589,14 @@ export class Adapter {
1600
1589
  if (!tokenParam) {
1601
1590
  throw new AdapterError('InternalError', `missing continuation token request parameter name ${tokenResp.name} for operation ${method.name}`, (_b = method.__raw) === null || _b === void 0 ? void 0 : _b.node);
1602
1591
  }
1592
+ else if (tokenParam.kind !== 'headerScalar' && tokenParam.kind !== 'queryScalar') {
1593
+ throw new AdapterError('InternalError', `unexpected continuation token request parameter kind ${tokenParam.kind} for operation ${method.name}`, (_c = method.__raw) === null || _c === void 0 ? void 0 : _c.node);
1594
+ }
1603
1595
  requestToken = tokenParam;
1604
1596
  break;
1605
1597
  }
1606
1598
  default:
1607
- throw new AdapterError('InternalError', `unhandled continuationTokenParameterSegment kind ${tokenReq.kind}`, (_c = tokenReq.__raw) === null || _c === void 0 ? void 0 : _c.node);
1599
+ throw new AdapterError('InternalError', `unhandled continuationTokenParameterSegment kind ${tokenReq.kind}`, (_d = tokenReq.__raw) === null || _d === void 0 ? void 0 : _d.node);
1608
1600
  }
1609
1601
  // find the continuation token response
1610
1602
  let responseToken;
@@ -1616,7 +1608,7 @@ export class Adapter {
1616
1608
  case 'responseheader': {
1617
1609
  const tokenHeader = respHeadersMap.get(tokenResp);
1618
1610
  if (!tokenHeader) {
1619
- throw new AdapterError('InternalError', `missing continuation token response header name ${tokenResp.name} for operation ${method.name}`, (_d = method.__raw) === null || _d === void 0 ? void 0 : _d.node);
1611
+ throw new AdapterError('InternalError', `missing continuation token response header name ${tokenResp.name} for operation ${method.name}`, (_e = method.__raw) === null || _e === void 0 ? void 0 : _e.node);
1620
1612
  }
1621
1613
  if (tokenHeader.kind !== 'responseHeaderScalar') {
1622
1614
  throw new AdapterError('InternalError', `unexpected response header kind ${tokenHeader.kind}`);
@@ -1625,7 +1617,7 @@ export class Adapter {
1625
1617
  break;
1626
1618
  }
1627
1619
  default:
1628
- throw new AdapterError('InternalError', `missing continuation token`, (_e = method.__raw) === null || _e === void 0 ? void 0 : _e.node);
1620
+ throw new AdapterError('InternalError', `missing continuation token`, (_f = method.__raw) === null || _f === void 0 ? void 0 : _f.node);
1629
1621
  }
1630
1622
  return new rust.PageableStrategyContinuationToken(requestToken, responseToken);
1631
1623
  }
@@ -1634,6 +1626,39 @@ export class Adapter {
1634
1626
  return undefined;
1635
1627
  }
1636
1628
  }
1629
+ /**
1630
+ * returns the array of pageable method parameters for reinjection.
1631
+ * if no parameters require reinjection, the array is empty.
1632
+ *
1633
+ * @param method the pageable method
1634
+ * @param paramsMap maps tcgc method params to Rust params
1635
+ * @returns an array containing the method parameters for reinjection
1636
+ */
1637
+ adaptPageableMethodReinjectionParams(method, paramsMap) {
1638
+ var _a;
1639
+ if (!method.pagingMetadata.nextLinkReInjectedParametersSegments) {
1640
+ return [];
1641
+ }
1642
+ const paramsForReinjection = new Array();
1643
+ for (const reinjectedParamSegment of method.pagingMetadata.nextLinkReInjectedParametersSegments) {
1644
+ for (const reinjectedParam of reinjectedParamSegment) {
1645
+ if (reinjectedParam.kind !== 'method') {
1646
+ throw new Error('unexpected param kind');
1647
+ }
1648
+ const rustParam = paramsMap.get(reinjectedParam);
1649
+ if (!rustParam) {
1650
+ throw new AdapterError('InternalError', `missing reinjection parameter name ${reinjectedParam.name} for operation ${method.name}`, (_a = method.__raw) === null || _a === void 0 ? void 0 : _a.node);
1651
+ }
1652
+ else if (rustParam.kind === 'headerScalar') {
1653
+ // we only care about the query params here.
1654
+ // any header parameters are handled elsewhere.
1655
+ continue;
1656
+ }
1657
+ paramsForReinjection.push(rustParam);
1658
+ }
1659
+ }
1660
+ return paramsForReinjection;
1661
+ }
1637
1662
  /**
1638
1663
  * converts a tcgc operation parameter into a Rust method parameter
1639
1664
  *
@@ -1719,7 +1744,7 @@ export class Adapter {
1719
1744
  adaptedParam = new rust.HeaderCollectionParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, format);
1720
1745
  }
1721
1746
  else if (param.serializedName === 'x-ms-meta') {
1722
- if (paramType.kind !== 'hashmap') {
1747
+ if (paramType.kind !== 'hashmap' && !isRefHashMap(paramType)) {
1723
1748
  throw new AdapterError('InternalError', `unexpected kind ${paramType.kind} for header ${param.serializedName}`, (_d = param.__raw) === null || _d === void 0 ? void 0 : _d.node);
1724
1749
  }
1725
1750
  adaptedParam = new rust.HeaderHashMapParameter(paramName, param.serializedName, paramLoc, param.optional, paramType);
@@ -1753,7 +1778,7 @@ export class Adapter {
1753
1778
  if (isRefSlice(paramType)) {
1754
1779
  adaptedParam = new rust.PathCollectionParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, param.allowReserved, style, param.explode);
1755
1780
  }
1756
- else if (paramType.kind === 'hashmap') {
1781
+ else if (paramType.kind === 'hashmap' || isRefHashMap(paramType)) {
1757
1782
  adaptedParam = new rust.PathHashMapParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, param.allowReserved, style, param.explode);
1758
1783
  }
1759
1784
  else {
@@ -1779,7 +1804,7 @@ export class Adapter {
1779
1804
  // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
1780
1805
  adaptedParam = new rust.QueryCollectionParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, true, format);
1781
1806
  }
1782
- else if (paramType.kind === 'hashmap') {
1807
+ else if (paramType.kind === 'hashmap' || isRefHashMap(paramType)) {
1783
1808
  // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
1784
1809
  adaptedParam = new rust.QueryHashMapParameter(paramName, param.serializedName, paramLoc, param.optional, paramType, true, param.explode);
1785
1810
  }
@@ -1851,6 +1876,16 @@ export class Adapter {
1851
1876
  }
1852
1877
  case 'encodedBytes':
1853
1878
  return this.getRefType(this.getEncodedBytes(type.encoding, true));
1879
+ case 'decimal':
1880
+ case 'Etag':
1881
+ case 'hashmap':
1882
+ case 'jsonValue':
1883
+ case 'offsetDateTime':
1884
+ case 'safeint':
1885
+ case 'Url':
1886
+ // these types all require conversion
1887
+ // to String so we don't need to own them
1888
+ return this.getRefType(type);
1854
1889
  }
1855
1890
  return undefined;
1856
1891
  }
@@ -1963,6 +1998,10 @@ export class Adapter {
1963
1998
  }
1964
1999
  }
1965
2000
  }
2001
+ /** type guard to determine if type is a Ref<HashMap> */
2002
+ function isRefHashMap(type) {
2003
+ return shared.asTypeOf(type, 'hashmap', 'ref') !== undefined;
2004
+ }
1966
2005
  /** type guard to determine if type is a Ref<Slice> */
1967
2006
  function isRefSlice(type) {
1968
2007
  return shared.asTypeOf(type, 'slice', 'ref') !== undefined;