Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
version = "3.8.3"
version = "3.10.1"
runner.dialect = scala3
maxColumn = 120
9 changes: 8 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ val zioVersion = "2.1.22"

val zioJsonVersion = "0.7.45"

// NOTE: update from 2.38.3 to 2.38.4 causes compilation error with some recursive types on codec derivation
val jsoniterVersion = "2.38.2"

val munitVersion = "1.2.1"
Expand All @@ -66,7 +67,13 @@ lazy val root = (project in file("."))
// for supporting code inspection / testing of generated code via test_gen.sh script
lazy val testLocal = (project in file("test-local"))
.settings(
libraryDependencies ++= dependencyByConfig("Sttp4", "Jsoniter", "ZioChunk")
libraryDependencies ++= Seq(
"com.softwaremill.sttp.client4" %% "core" % sttpClient4Version,
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % jsoniterVersion,
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % jsoniterVersion % "compile-internal",
"dev.zio" %% "zio-json" % zioJsonVersion,
"dev.zio" %% "zio" % zioVersion
)
)
.settings(noPublish)

Expand Down
6 changes: 3 additions & 3 deletions modules/cli/src/main/scala/cli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ private def argsToTask(args: Seq[String]): Either[String, Task] =
jsonCodec = jsonCodec,
preprocess = s => {
incResources.partitionMap(s => if s.startsWith("!") then Left(s.stripPrefix("!")) else Right(s)) match
case (Nil, Nil) => s
case (excl, Nil) => s.copy(resources = s.resources.view.filterKeys(!_.hasMatch(excl)).toMap)
case (Nil, incl) => s.copy(resources = s.resources.view.filterKeys(_.hasMatch(incl)).toMap)
case (Nil, Nil) => s
case (excl, Nil) => s.copy(resources = s.resources.view.filterKeys(!_.hasMatch(excl)).toMap)
case (Nil, incl) => s.copy(resources = s.resources.view.filterKeys(_.hasMatch(incl)).toMap)
case (excl, incl) =>
s.copy(resources = s.resources.view.filterKeys(k => !k.hasMatch(excl) && k.hasMatch(incl)).toMap)
},
Expand Down
41 changes: 24 additions & 17 deletions modules/core/shared/src/main/scala/codegen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,18 @@ def generateBySpec(
if specs.endpoints.nonEmpty then "enum Endpoint(val location: String, val url: Uri):" else "",
specs.endpoints
.map(e =>
// for cases where location is not unique we will append numbers
val locationPostfix = specs.endpoints
.collect { case Endpoint(location = e.location, endpointUrl = endpointUrl) =>
endpointUrl
}
.zipWithIndex
.collectFirst { case (e.endpointUrl, idx) if idx > 0 => (idx + 1).toString() }
.getOrElse("")

s"""${toComment(
Some(e.description)
)} case `${e.location}` extends Endpoint("${e.location}", uri"${e.endpointUrl}")""".stripMargin
)} case `${e.location}$locationPostfix` extends Endpoint("${e.location}", uri"${e.endpointUrl}")""".stripMargin
)
.mkString("\n")
).mkString("\n")
Expand Down Expand Up @@ -220,7 +229,7 @@ def generateBySpec(
hasProps = p => specs.hasProps(p),
arrType = config.arrayType
) match
case None => Nil
case None => Nil
case Some(codecs) =>
Files.writeString(commonCodecsPath, codecs)
List(commonCodecsPath.toFile())
Expand Down Expand Up @@ -301,10 +310,9 @@ def resourceCode(
"\\{(.*?)\\}".r.findAllIn(s).toList match
case Nil => s"PathSegment(\"$s\")"
case v :: Nil if v == s => "PathSegment(" + toScalaName(v.stripPrefix("{").stripSuffix("}")) + ")"
case vars =>
"PathSegment(s\"" + vars.foldLeft(s)((res, v) =>
res.replace(v, "$" + v.stripPrefix("{").stripSuffix("}"))
) + "\")"
case vars =>
"PathSegment(s\"" + vars
.foldLeft(s)((res, v) => res.replace(v, "$" + v.stripPrefix("{").stripSuffix("}"))) + "\")"
)

val req = method.mediaUploads match
Expand Down Expand Up @@ -362,15 +370,14 @@ def resourceCode(

val queryParams = "\n val params = " +
(method.scalaQueryParams match
case Nil => "commonQueryParams.value"
case Nil => "commonQueryParams.value"
case qParams =>
qParams
.map {
case (k, p) if p.required => s"""Map("$k" -> $k)"""
case (k, p) => s"""$k.map(p => Map("$k" -> p.toString)).getOrElse(Map.empty)"""
}
.mkString("", " ++ ", " ++ commonQueryParams.value\n")
)
.mkString("", " ++ ", " ++ commonQueryParams.value\n"))

def responseType(t: String) =
httpSource match
Expand Down Expand Up @@ -459,7 +466,7 @@ def schemasCode(
s"package $pkg",
"",
jsonCodec match {
case JsonCodec.ZioJson => "import zio.json.*"
case JsonCodec.ZioJson => "import zio.json.*"
case JsonCodec.Jsoniter =>
"""|import com.github.plokhotnyuk.jsoniter_scala.core.*
|import com.github.plokhotnyuk.jsoniter_scala.macros.*""".stripMargin
Expand Down Expand Up @@ -492,7 +499,7 @@ def commonSchemaCodecs(
}
)
.distinct match
case Nil => None
case Nil => None
case props =>
Some(
List(
Expand Down Expand Up @@ -631,7 +638,7 @@ def readResources(
resources match
case (k, v) :: xs =>
v.obj.remove("resources").map(_.obj) match
case None => readResources(xs, result.updated(k, read[Resource](v)))
case None => readResources(xs, result.updated(k, read[Resource](v)))
case Some(obj) =>
val newRes = obj.map((a, b) => ResourcePath(k, a) -> b).toList ::: xs
Try(read[Resource](v)) match
Expand Down Expand Up @@ -727,8 +734,8 @@ enum SchemaType(val optional: Boolean):
case Primitive("number", _, Some("double" | "float")) => toType("Double")
case Primitive("boolean", _, _) => toType("Boolean")
case Ref(ref, _) => toType(ref.scalaName)
case Array(t, _) => toType(arrayType.toScalaType(t.scalaType(arrayType, enumType)))
case Object(t, _) => toType(s"Map[String, ${t.scalaType(arrayType)}]")
case Array(t, _) => toType(arrayType.toScalaType(t.scalaType(arrayType, enumType)))
case Object(t, _) => toType(s"Map[String, ${t.scalaType(arrayType)}]")
case Enum(_, values, _) =>
enumType match
case SchemaType.EnumType.Literal => toType(values.map(v => v.value).mkString("\"", "\" | \"", "\""))
Expand Down Expand Up @@ -777,7 +784,7 @@ object SchemaType:
case _ =>
o.value.get("$ref").map(_.str) match
case Some(ref) => SchemaType.Ref(SchemaPath(ref), optional)
case _ =>
case _ =>
if !o.value.keySet.contains("properties") then
if Set("uploadType", "upload_protocol").exists(context.jsonPath.lastOption.contains) then
""""([\w]+)"""".r
Expand Down Expand Up @@ -852,7 +859,7 @@ object Schema:
result: Map[SchemaPath, Schema]
): Map[SchemaPath, Schema] =
schemas match {
case Nil => result
case Nil => result
case (name, data) :: xs =>
val schema = readSchema(name, data)

Expand All @@ -862,7 +869,7 @@ object Schema:
case None => Nil
case Some(p) => List((p, p.jsonPath.foldLeft(o)(_.apply(_).obj)))
} match {
case Nil => readSchemas(xs, result.updated(name, schema))
case Nil => readSchemas(xs, result.updated(name, schema))
case nested =>
readSchemas(nested ::: xs, result.updated(name, schema))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
package gcp.pubsub.v1.sttp4_jsoniter_ziochunk

import gcp.pubsub.v1.sttp4_jsoniter_ziochunk.schemas.*
import com.github.plokhotnyuk.jsoniter_scala.core.readFromString

class PubsubJsoniterCodecSpec extends munit.FunSuite {
test("PublishMessage") {
test("PublishMessage with ordering key") {
val pMsg = PubsubMessage(data = Some("data"), attributes = Some(Map("key" -> "value")), orderingKey = Some("key"))
val expected = """{"data":"data","attributes":{"key":"value"},"orderingKey":"key"}"""
val expected = """{"attributes":{"key":"value"},"orderingKey":"key","data":"data"}"""
val encoded = pMsg.toJsonString

assert(encoded == expected)

val decoded = readFromString[PubsubMessage](expected)
assert(pMsg == decoded)
}

test("PublishMessage no ordering key") {
val pMsg = PubsubMessage(data = Some("data"), attributes = Some(Map("key" -> "value")))
val expected = """{"data":"data","attributes":{"key":"value"}}"""
val expected = """{"attributes":{"key":"value"},"data":"data"}"""
val encoded = pMsg.toJsonString

assert(encoded == expected)

val decoded = readFromString[PubsubMessage](expected)
assert(pMsg == decoded)
}

test("PublishMessage no ordering key, no attributes") {
Expand All @@ -25,5 +32,8 @@ class PubsubJsoniterCodecSpec extends munit.FunSuite {
val encoded = pMsg.toJsonString

assert(encoded == expected)

val decoded = readFromString[PubsubMessage](expected)
assert(pMsg == decoded)
}
}
Loading