Skip to content

Commit 0a9c2a8

Browse files
support of option fields
1 parent 05706ee commit 0a9c2a8

2 files changed

Lines changed: 32 additions & 10 deletions

File tree

modules/openapi-generator/src/main/resources/scala-sttp4-jsoniter/helpers.mustache

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,21 @@ enum PathStyleFormat:
3535
inline def allLabels[T <: Tuple]: List[String] =
3636
constValueTuple[T].toList.asInstanceOf[List[String]]
3737

38-
inline def checkFields[T <: Tuple]: Unit =
38+
private inline def checkFields[T <: Tuple]: Unit =
3939
inline erasedValue[T] match {
4040
case _: EmptyTuple => ()
4141
case _: (t *: ts) =>
4242
inline erasedValue[t] match
4343
case _: Primitive => checkFields[ts]
44+
case _: Option[Primitive] => checkFields[ts]
4445
case _ => error("Cannot derive structure, structure must consist only of primitive fields")
4546
}
4647

48+
private val flattenKeyVals: Primitive | Option[Primitive] => Option[Primitive] = {
49+
case p: Primitive => Some(p)
50+
case opt: Option[Primitive] => opt
51+
}
52+
4753
trait FormSerializable[T]:
4854
inline def serialize(
4955
name: String,
@@ -82,7 +88,9 @@ object FormSerializable:
8288
checkFields[mirror.MirroredElemTypes]
8389
val labels = allLabels[mirror.MirroredElemLabels]
8490
optObj.map { obj =>
85-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]])
91+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
92+
.filter((_, v) => v.isDefined)
93+
.map((k, v) => (k, v.get))
8694
serializeModel(name, keyVals, format, explode)
8795
}.getOrElse(Seq.empty[(String, String)])
8896
case mirror: Mirror.SumOf[t] => optObj.map(v => (name, writeToString(v)(summonInline[JsonValueCodec[mirror.MirroredMonoType]]))).toSeq
@@ -93,7 +101,9 @@ object FormSerializable:
93101
case mirror: Mirror.ProductOf[T] =>
94102
checkFields[mirror.MirroredElemTypes] // Stripe ma IDGAF bo używają deepObject np. tak lines[0][tax_amounts][0][amount] - mimo tego że spec na to nie pozwala
95103
val labels = allLabels[mirror.MirroredElemLabels]
96-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]]).toSeq
104+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
105+
.filter((_, v) => v.isDefined)
106+
.map((k, v) => (k, v.get))
97107
serializeModel(name, keyVals, format, explode)
98108
}
99109

@@ -180,7 +190,9 @@ object HeaderSerializable:
180190
checkFields[mirror.MirroredElemTypes]
181191
val labels = allLabels[mirror.MirroredElemLabels]
182192
optObj.map { obj =>
183-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]].map(_.toString))
193+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
194+
.filter((_, v) => v.isDefined)
195+
.map((k, v) => (k, v.get.toString))
184196
inline if explode then
185197
Map(name ->keyVals.map((k, v) => s"$k=$v").mkString(","))
186198
else
@@ -192,7 +204,9 @@ object HeaderSerializable:
192204
case mirror: Mirror.ProductOf[T] =>
193205
checkFields[mirror.MirroredElemTypes]
194206
val labels = allLabels[mirror.MirroredElemLabels]
195-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]].map(_.toString))
207+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
208+
.filter((_, v) => v.isDefined)
209+
.map((k, v) => (k, v.get.toString))
196210
inline if explode then
197211
Map(name ->keyVals.map((k, v) => s"$k=$v").mkString(","))
198212
else
@@ -228,7 +242,9 @@ object PathSerializable:
228242
checkFields[mirror.MirroredElemTypes]
229243
val labels = allLabels[mirror.MirroredElemLabels]
230244
optObj.map { obj =>
231-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]])
245+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
246+
.filter((_, v) => v.isDefined)
247+
.map((k, v) => (k, v.get))
232248
serializeModel(name, keyVals, style, explode)
233249
}.getOrElse("")
234250
case mirror: Mirror.SumOf[t] => optObj.map(writeToString(_)(summonInline[JsonValueCodec[mirror.MirroredMonoType]])).getOrElse("")
@@ -239,7 +255,9 @@ object PathSerializable:
239255
case mirror: Mirror.ProductOf[T] =>
240256
checkFields[mirror.MirroredElemTypes]
241257
val labels = allLabels[mirror.MirroredElemLabels]
242-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]]).toSeq
258+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
259+
.filter((_, v) => v.isDefined)
260+
.map((k, v) => (k, v.get))
243261
serializeModel(name, keyVals, style, explode)
244262
}
245263

@@ -315,7 +333,9 @@ object CookieSerializable:
315333
checkFields[mirror.MirroredElemTypes]
316334
val labels = allLabels[mirror.MirroredElemLabels]
317335
optObj.map { obj =>
318-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]])
336+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
337+
.filter((_, v) => v.isDefined)
338+
.map((k, v) => (k, v.get))
319339
serializeModel(name, keyVals, explode)
320340
}.getOrElse(Seq.empty[(String, String)])
321341
case mirror: Mirror.SumOf[t] => optObj.map(v => (name, writeToString(v)(summonInline[JsonValueCodec[mirror.MirroredMonoType]]))).toSeq
@@ -326,7 +346,9 @@ object CookieSerializable:
326346
case mirror: Mirror.ProductOf[T] =>
327347
checkFields[mirror.MirroredElemTypes]
328348
val labels = allLabels[mirror.MirroredElemLabels]
329-
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive]]).toSeq
349+
val keyVals = labels.zip(obj.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Primitive | Option[Primitive]]].map(flattenKeyVals))
350+
.filter((_, v) => v.isDefined)
351+
.map((k, v) => (k, v.get))
330352
serializeModel(name, keyVals, explode)
331353
}
332354

modules/openapi-generator/src/main/resources/scala-sttp4-jsoniter/model.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object {{classname}}:
4444
.withAdtLeafClassNameMapper { x =>
4545
JsonCodecMaker.simpleClassName(x) match
4646
{{#values}}
47-
case "{{#fnEnumEntry}}{{.}}{{/fnEnumEntry}}" => "{{.}}"
47+
case "{{#fnEnumLeaf}}{{.}}{{/fnEnumLeaf}}" => "{{.}}"
4848
{{/values}}
4949
}{{/allowableValues}}
5050
.withDiscriminatorFieldName(scala.None)

0 commit comments

Comments
 (0)