33* Licensed under the MIT License. See License.txt in the project root for license information.
44*--------------------------------------------------------------------------------------------*/
55
6- // cspell: ignore addl responseheader subclients lropaging
6+ // cspell: ignore addl requiredness responseheader subclients lropaging
77
88import * as tsp from '@typespec/compiler' ;
99import * as http from '@typespec/http' ;
@@ -1593,7 +1593,7 @@ export class Adapter {
15931593 ) {
15941594 adaptedParam = this . adaptMethodSpreadParameter ( param , this . adaptPayloadFormat ( opParam . defaultContentType ) , opParam . type ) ;
15951595 } else {
1596- adaptedParam = this . adaptMethodParameter ( opParam ) ;
1596+ adaptedParam = this . adaptMethodParameter ( opParam , param ) ;
15971597 }
15981598
15991599 switch ( adaptedParam . kind ) {
@@ -2104,12 +2104,17 @@ export class Adapter {
21042104 }
21052105
21062106 /**
2107- * converts a tcgc operation parameter into a Rust method parameter
2107+ * converts a tcgc operation parameter into a Rust method parameter.
2108+ * note that when methodParam is present, we must use all applicable
2109+ * values from methodParam as the source of truth. e.g. when overriding
2110+ * a method to make an optional param required, the requiredness will
2111+ * be reflected in the method param, _not_ the operation param.
21082112 *
2109- * @param param the tcgc operation parameter to convert
2113+ * @param opParam the tcgc operation parameter to convert
2114+ * @param methodParam the tcgc method parameter associated with opParam
21102115 * @returns a Rust method parameter
21112116 */
2112- private adaptMethodParameter ( param : tcgc . SdkHttpParameter ) : rust . MethodParameter {
2117+ private adaptMethodParameter ( opParam : tcgc . SdkHttpParameter , methodParam ?: tcgc . SdkMethodParameter ) : rust . MethodParameter {
21132118 /**
21142119 * used to create keys for this.clientMethodParams
21152120 * @param param the param for which to create a key
@@ -2121,11 +2126,11 @@ export class Adapter {
21212126 return `${ param . name } -${ param . kind } ` ;
21222127 } ;
21232128
2124- const paramLoc = param . onClient ? 'client' : 'method' ;
2129+ const paramLoc = opParam . onClient ? 'client' : 'method' ;
21252130
21262131 // if this is a client method param, check if we've already adapted it
21272132 if ( paramLoc === 'client' ) {
2128- const clientMethodParam = this . clientMethodParams . get ( getClientParamsKey ( param ) ) ;
2133+ const clientMethodParam = this . clientMethodParams . get ( getClientParamsKey ( opParam ) ) ;
21292134 if ( clientMethodParam ) {
21302135 return clientMethodParam ;
21312136 }
@@ -2143,59 +2148,60 @@ export class Adapter {
21432148 return param . name ;
21442149 } ;
21452150
2146- const paramName = naming . getEscapedReservedName ( utils . snakeCaseName ( getCorrespondingClientParamName ( param ) ) , 'param' , reservedParams ) ;
2147- let paramType = this . getType ( param . type ) ;
2151+ const paramName = naming . getEscapedReservedName ( utils . snakeCaseName ( getCorrespondingClientParamName ( opParam ) ) , 'param' , reservedParams ) ;
2152+ const paramOptional = methodParam ? methodParam . optional : opParam . optional ;
2153+ let paramType = this . getType ( methodParam ? methodParam . type : opParam . type ) ;
21482154
21492155 // for required header/path/query method string params, we might emit them as borrowed types
2150- if ( ! param . optional && ! param . onClient && ( param . kind === 'header' || param . kind === 'path' || param . kind === 'query' ) ) {
2151- const borrowedType = this . canBorrowMethodParam ( paramType , param . kind ) ;
2156+ if ( ! paramOptional && paramLoc !== 'client' && ( opParam . kind === 'header' || opParam . kind === 'path' || opParam . kind === 'query' ) ) {
2157+ const borrowedType = this . canBorrowMethodParam ( paramType , opParam . kind ) ;
21522158 if ( borrowedType ) {
21532159 paramType = borrowedType ;
21542160 }
21552161 }
21562162
21572163 let adaptedParam : rust . MethodParameter ;
2158- switch ( param . kind ) {
2164+ switch ( opParam . kind ) {
21592165 case 'body' : {
21602166 let requestType : rust . Bytes | rust . Payload ;
2161- if ( param . type . kind === 'bytes' && param . type . encode === 'bytes' ) {
2167+ if ( opParam . type . kind === 'bytes' && opParam . type . encode === 'bytes' ) {
21622168 // bytes encoding indicates a streaming binary request
21632169 requestType = new rust . Bytes ( this . crate ) ;
21642170 } else {
2165- requestType = new rust . Payload ( this . typeToWireType ( paramType ) , this . adaptPayloadFormat ( param . defaultContentType ) ) ;
2171+ requestType = new rust . Payload ( this . typeToWireType ( paramType ) , this . adaptPayloadFormat ( opParam . defaultContentType ) ) ;
21662172 }
2167- const requestFormatType = this . adaptPayloadFormatType ( param . defaultContentType ) ;
2168- adaptedParam = new rust . BodyParameter ( paramName , paramLoc , param . optional , new rust . RequestContent ( this . crate , requestType , requestFormatType ) ) ;
2173+ const requestFormatType = this . adaptPayloadFormatType ( opParam . defaultContentType ) ;
2174+ adaptedParam = new rust . BodyParameter ( paramName , paramLoc , paramOptional , new rust . RequestContent ( this . crate , requestType , requestFormatType ) ) ;
21692175 break ;
21702176 }
21712177 case 'cookie' :
21722178 // TODO: https://github.com/Azure/typespec-rust/issues/192
2173- throw new AdapterError ( 'UnsupportedTsp' , 'cookie parameters are not supported' , param . __raw ?. node ) ;
2179+ throw new AdapterError ( 'UnsupportedTsp' , 'cookie parameters are not supported' , opParam . __raw ?. node ) ;
21742180 case 'header' :
2175- if ( param . collectionFormat ) {
2181+ if ( opParam . collectionFormat ) {
21762182 if ( paramType . kind !== 'Vec' && ! isRefSlice ( paramType ) ) {
2177- throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for HeaderCollectionParameter` , param . __raw ?. node ) ;
2183+ throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for HeaderCollectionParameter` , opParam . __raw ?. node ) ;
21782184 }
21792185 let format : rust . CollectionFormat ;
2180- switch ( param . collectionFormat ) {
2186+ switch ( opParam . collectionFormat ) {
21812187 case 'csv' :
21822188 case 'simple' :
21832189 format = 'csv' ;
21842190 break ;
21852191 case 'pipes' :
21862192 case 'ssv' :
21872193 case 'tsv' :
2188- format = param . collectionFormat ;
2194+ format = opParam . collectionFormat ;
21892195 break ;
21902196 default :
2191- throw new AdapterError ( 'InternalError' , `unexpected format ${ param . collectionFormat } for HeaderCollectionParameter` , param . __raw ?. node ) ;
2197+ throw new AdapterError ( 'InternalError' , `unexpected format ${ opParam . collectionFormat } for HeaderCollectionParameter` , opParam . __raw ?. node ) ;
21922198 }
2193- adaptedParam = new rust . HeaderCollectionParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , format ) ;
2194- } else if ( param . serializedName === 'x-ms-meta' ) {
2199+ adaptedParam = new rust . HeaderCollectionParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , format ) ;
2200+ } else if ( opParam . serializedName === 'x-ms-meta' ) {
21952201 if ( paramType . kind !== 'hashmap' && ! isRefHashMap ( paramType ) ) {
2196- throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for header ${ param . serializedName } ` , param . __raw ?. node ) ;
2202+ throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for header ${ opParam . serializedName } ` , opParam . __raw ?. node ) ;
21972203 }
2198- adaptedParam = new rust . HeaderHashMapParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType ) ;
2204+ adaptedParam = new rust . HeaderHashMapParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType ) ;
21992205 } else {
22002206 paramType = this . typeToWireType ( paramType ) ;
22012207 switch ( paramType . kind ) {
@@ -2205,70 +2211,70 @@ export class Adapter {
22052211 case 'slice' :
22062212 case 'str' :
22072213 case 'Vec' :
2208- throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for scalar header ${ param . serializedName } ` , param . __raw ?. node ) ;
2214+ throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for scalar header ${ opParam . serializedName } ` , opParam . __raw ?. node ) ;
22092215 }
2210- adaptedParam = new rust . HeaderScalarParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType ) ;
2211- adaptedParam . isApiVersion = param . isApiVersionParam ;
2216+ adaptedParam = new rust . HeaderScalarParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType ) ;
2217+ adaptedParam . isApiVersion = opParam . isApiVersionParam ;
22122218 }
22132219 break ;
22142220 case 'path' : {
22152221 paramType = this . typeToWireType ( paramType ) ;
22162222 let style : rust . ParameterStyle = 'simple' ;
2217- const tspStyleString = ( param . style as string ) ;
2223+ const tspStyleString = ( opParam . style as string ) ;
22182224 if ( ! [ 'simple' , 'path' , 'label' , 'matrix' ] . includes ( tspStyleString ) ) {
2219- throw new AdapterError ( 'InternalError' , `unsupported style ${ tspStyleString } for parameter ${ param . serializedName } ` , param . __raw ?. node ) ;
2225+ throw new AdapterError ( 'InternalError' , `unsupported style ${ tspStyleString } for parameter ${ opParam . serializedName } ` , opParam . __raw ?. node ) ;
22202226 } else {
22212227 style = tspStyleString as rust . ParameterStyle ;
22222228 }
22232229
22242230 if ( isRefSlice ( paramType ) ) {
2225- adaptedParam = new rust . PathCollectionParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , param . allowReserved , style , param . explode ) ;
2231+ adaptedParam = new rust . PathCollectionParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , opParam . allowReserved , style , opParam . explode ) ;
22262232 } else if ( paramType . kind === 'hashmap' || isRefHashMap ( paramType ) ) {
2227- adaptedParam = new rust . PathHashMapParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , param . allowReserved , style , param . explode ) ;
2233+ adaptedParam = new rust . PathHashMapParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , opParam . allowReserved , style , opParam . explode ) ;
22282234 } else {
22292235 switch ( paramType . kind ) {
22302236 case 'jsonValue' :
22312237 case 'model' :
22322238 case 'slice' :
22332239 case 'str' :
22342240 case 'Vec' :
2235- throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for scalar path ${ param . serializedName } ` , param . __raw ?. node ) ;
2241+ throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for scalar path ${ opParam . serializedName } ` , opParam . __raw ?. node ) ;
22362242 }
22372243
2238- adaptedParam = new rust . PathScalarParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , param . allowReserved , style ) ;
2244+ adaptedParam = new rust . PathScalarParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , opParam . allowReserved , style ) ;
22392245 }
22402246 } break ;
22412247 case 'query' :
22422248 paramType = this . typeToWireType ( paramType ) ;
22432249 if ( paramType . kind === 'Vec' || isRefSlice ( paramType ) ) {
2244- let format : rust . ExtendedCollectionFormat = param . explode ? 'multi' : 'csv' ;
2245- if ( param . collectionFormat ) {
2246- format = param . collectionFormat === 'simple' ? 'csv' : ( param . collectionFormat === 'form' ? 'multi' : param . collectionFormat ) ;
2250+ let format : rust . ExtendedCollectionFormat = opParam . explode ? 'multi' : 'csv' ;
2251+ if ( opParam . collectionFormat ) {
2252+ format = opParam . collectionFormat === 'simple' ? 'csv' : ( opParam . collectionFormat === 'form' ? 'multi' : opParam . collectionFormat ) ;
22472253 }
22482254 // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
2249- adaptedParam = new rust . QueryCollectionParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , true , format ) ;
2255+ adaptedParam = new rust . QueryCollectionParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , true , format ) ;
22502256 } else if ( paramType . kind === 'hashmap' || isRefHashMap ( paramType ) ) {
22512257 // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
2252- adaptedParam = new rust . QueryHashMapParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , true , param . explode ) ;
2258+ adaptedParam = new rust . QueryHashMapParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , true , opParam . explode ) ;
22532259 } else {
22542260 switch ( paramType . kind ) {
22552261 case 'jsonValue' :
22562262 case 'model' :
22572263 case 'slice' :
22582264 case 'str' :
2259- throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for scalar query ${ param . serializedName } ` , param . __raw ?. node ) ;
2265+ throw new AdapterError ( 'InternalError' , `unexpected kind ${ paramType . kind } for scalar query ${ opParam . serializedName } ` , opParam . __raw ?. node ) ;
22602266 }
22612267 // TODO: hard-coded encoding setting, https://github.com/Azure/typespec-azure/issues/1314
2262- adaptedParam = new rust . QueryScalarParameter ( paramName , param . serializedName , paramLoc , param . optional , paramType , true ) ;
2263- adaptedParam . isApiVersion = param . isApiVersionParam ;
2268+ adaptedParam = new rust . QueryScalarParameter ( paramName , opParam . serializedName , paramLoc , paramOptional , paramType , true ) ;
2269+ adaptedParam . isApiVersion = opParam . isApiVersionParam ;
22642270 }
22652271 break ;
22662272 }
22672273
2268- adaptedParam . docs = this . adaptDocs ( param . summary , param . doc ) ;
2274+ adaptedParam . docs = this . adaptDocs ( methodParam ? methodParam . summary : opParam . summary , methodParam ? methodParam . doc : opParam . doc ) ;
22692275
22702276 if ( paramLoc === 'client' ) {
2271- this . clientMethodParams . set ( getClientParamsKey ( param ) , adaptedParam ) ;
2277+ this . clientMethodParams . set ( getClientParamsKey ( opParam ) , adaptedParam ) ;
22722278 }
22732279
22742280 return adaptedParam ;
0 commit comments