Skip to content

Commit

Permalink
Merge branch 'LeonPoon-fixes'
Browse files Browse the repository at this point in the history
  • Loading branch information
julianpeeters committed Oct 1, 2023
2 parents 742f149 + 94551e6 commit 68aa44d
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 14 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ _Note:_ Currently [Treehugger](http://eed3si9n.com/treehugger/comments.html#Scal

##### Get the dependency with:

"com.julianpeeters" %% "avrohugger-core" % "1.5.5"
"com.julianpeeters" %% "avrohugger-core" % "1.5.6"


##### Description:
Expand Down Expand Up @@ -209,7 +209,7 @@ namespace rewritten. Multiple conflicting wildcards are not permitted.

##### Get the dependency with:

"com.julianpeeters" %% "avrohugger-filesorter" % "1.5.5"
"com.julianpeeters" %% "avrohugger-filesorter" % "1.5.6"


##### Description:
Expand All @@ -229,22 +229,22 @@ To ensure dependent schemas are compiled in the proper order (thus avoiding `org
#### `avrohugger-tools`


Download the avrohugger-tools jar for Scala [2.12](https://search.maven.org/remotecontent?filepath=com/julianpeeters/avrohugger-tools_2.12/1.5.5/avrohugger-tools_2.12-1.5.5-assembly.jar), or Scala [2.13](https://search.maven.org/remotecontent?filepath=com/julianpeeters/avrohugger-tools_2.13/1.5.5/avrohugger-tools_2.13-1.5.5-assembly.jar) (>30MB!) and use it like the avro-tools jar `Usage: [-string] (schema|protocol|datafile) input... outputdir`:
Download the avrohugger-tools jar for Scala [2.12](https://search.maven.org/remotecontent?filepath=com/julianpeeters/avrohugger-tools_2.12/1.5.6/avrohugger-tools_2.12-1.5.6-assembly.jar), or Scala [2.13](https://search.maven.org/remotecontent?filepath=com/julianpeeters/avrohugger-tools_2.13/1.5.6/avrohugger-tools_2.13-1.5.6-assembly.jar) (>30MB!) and use it like the avro-tools jar `Usage: [-string] (schema|protocol|datafile) input... outputdir`:


* `generate` generates Scala case class definitions:

`java -jar /path/to/avrohugger-tools_2.12-1.5.5-assembly.jar generate schema user.avsc . `
`java -jar /path/to/avrohugger-tools_2.12-1.5.6-assembly.jar generate schema user.avsc . `


* `generate-specific` generates definitions that extend Avro's `SpecificRecordBase`:

`java -jar /path/to/avrohugger-tools_2.12-1.5.5-assembly.jar generate-specific schema user.avsc . `
`java -jar /path/to/avrohugger-tools_2.12-1.5.6-assembly.jar generate-specific schema user.avsc . `


* `generate-scavro` (`@deprecated` since avrohugger v1.5.0) generates definitions that extend Scavro's `AvroSerializable`:

`java -jar /path/to/avrohugger-tools_2.12-1.5.5-assembly.jar generate-scavro schema user.avsc . `
`java -jar /path/to/avrohugger-tools_2.12-1.5.6-assembly.jar generate-scavro schema user.avsc . `


## Warnings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ object DefaultParamMatcher {
case Schema.Type.UNION =>
val schemas = avroSchema.getTypes.asScala.toList
if (avroSchema.isNullable) NONE
else if (schemas.size == 1 && !typeMatcher.avroScalaTypes.union.useCoproductForLoneNonNullType)
asDefaultParam(classStore, schemas.head, typeMatcher)
else if (schemas.size == 2 && typeMatcher.avroScalaTypes.union.useEitherForTwoNonNullTypes)
LEFT(asDefaultParam(classStore, schemas.head, typeMatcher))
else COPRODUCT(asDefaultParam(classStore, schemas.head, typeMatcher), schemas.map(typeMatcher.toScalaType(classStore, None, _).safeToString))
case Schema.Type.ARRAY =>
CustomDefaultParamMatcher.checkCustomArrayType(typeMatcher.avroScalaTypes.array) DOT "empty"
case Schema.Type.MAP =>
MAKE_MAP(LIT("") ANY_-> asDefaultParam(classStore, avroSchema.getValueType, typeMatcher))
ID("Map") DOT "empty"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ case object EnumAsScalaString extends AvroScalaEnumType
sealed trait AvroScalaUnionType extends Product with Serializable {
val useEitherForTwoNonNullTypes: Boolean = false

val useCoproductForLoneNonNullType: Boolean = false

}

case object OptionalShapelessCoproduct extends AvroScalaUnionType
case object OptionalShapelessCoproduct extends AvroScalaUnionType {
override val useCoproductForLoneNonNullType: Boolean = true
}
case object OptionShapelessCoproduct extends AvroScalaUnionType
case object OptionEitherShapelessCoproduct extends AvroScalaUnionType {
override val useEitherForTwoNonNullTypes: Boolean = true
Expand Down
16 changes: 16 additions & 0 deletions avrohugger-core/src/test/avro/unions_with_coproduct2.avsc
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
[
{
"namespace": "com.example.avrohugger.unions_with_coproduct_avsc2",
"name": "UnionOfOneNonNullType",
"type": "record",
"fields": [
{
"name": "f3",
"type": [
{
"type": "map",
"values": "string"
}
]
}
]
},
{
"namespace": "com.example.avrohugger.unions_with_coproduct_avsc2",
"name": "UnionOfNullWithOneNonNullType",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */
package com.example.avrohugger.unions_with_coproduct_avsc2

import scala.annotation.switch

final case class UnionOfOneNonNullType(var f3: Map[String, String]) extends org.apache.avro.specific.SpecificRecordBase {
def this() = this(Map.empty)
def get(field$: Int): AnyRef = {
(field$: @switch) match {
case 0 => {
f3
}.asInstanceOf[AnyRef]
case _ => new org.apache.avro.AvroRuntimeException("Bad index")
}
}
def put(field$: Int, value: Any): Unit = {
(field$: @switch) match {
case 0 => this.f3 = {
value
}.asInstanceOf[Map[String, String]]
case _ => new org.apache.avro.AvroRuntimeException("Bad index")
}
()
}
def getSchema: org.apache.avro.Schema = com.example.avrohugger.unions_with_coproduct_avsc2.UnionOfOneNonNullType.SCHEMA$
}

object UnionOfOneNonNullType {
val SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"UnionOfOneNonNullType\",\"namespace\":\"com.example.avrohugger.unions_with_coproduct_avsc2\",\"fields\":[{\"name\":\"f3\",\"type\":[{\"type\":\"map\",\"values\":\"string\"}]}]}")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */
package com.example.avrohugger.unions_with_coproduct_avsc2

import scala.annotation.switch

final case class UnionOfOneNonNullType(var f3: Map[String, String]) extends org.apache.avro.specific.SpecificRecordBase {
def this() = this(Map.empty)
def get(field$: Int): AnyRef = {
(field$: @switch) match {
case 0 => {
f3
}.asInstanceOf[AnyRef]
case _ => new org.apache.avro.AvroRuntimeException("Bad index")
}
}
def put(field$: Int, value: Any): Unit = {
(field$: @switch) match {
case 0 => this.f3 = {
value
}.asInstanceOf[Map[String, String]]
case _ => new org.apache.avro.AvroRuntimeException("Bad index")
}
()
}
def getSchema: org.apache.avro.Schema = com.example.avrohugger.unions_with_coproduct_avsc2.UnionOfOneNonNullType.SCHEMA$
}

object UnionOfOneNonNullType {
val SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"UnionOfOneNonNullType\",\"namespace\":\"com.example.avrohugger.unions_with_coproduct_avsc2\",\"fields\":[{\"name\":\"f3\",\"type\":[{\"type\":\"map\",\"values\":\"string\"}]}]}")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */
package com.example.avrohugger.unions_with_coproduct_avsc2

import scala.annotation.switch

import shapeless.{:+:, CNil, Coproduct}

final case class UnionOfOneNonNullType(var f3: Map[String, String] :+: CNil) extends org.apache.avro.specific.SpecificRecordBase {
def this() = this(shapeless.Coproduct[Map[String, String] :+: CNil](Map.empty))
def get(field$: Int): AnyRef = {
(field$: @switch) match {
case 0 => {
f3
}.asInstanceOf[AnyRef]
case _ => new org.apache.avro.AvroRuntimeException("Bad index")
}
}
def put(field$: Int, value: Any): Unit = {
(field$: @switch) match {
case 0 => this.f3 = {
value
}.asInstanceOf[Map[String, String] :+: CNil]
case _ => new org.apache.avro.AvroRuntimeException("Bad index")
}
()
}
def getSchema: org.apache.avro.Schema = com.example.avrohugger.unions_with_coproduct_avsc2.UnionOfOneNonNullType.SCHEMA$
}

object UnionOfOneNonNullType {
val SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"UnionOfOneNonNullType\",\"namespace\":\"com.example.avrohugger.unions_with_coproduct_avsc2\",\"fields\":[{\"name\":\"f3\",\"type\":[{\"type\":\"map\",\"values\":\"string\"}]}]}")
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import avrohugger.format.SpecificRecord
import avrohugger.types._
import org.specs2._
import org.specs2.execute.Result
import util.Util.containExpectedContentIn

import java.io.File
import scala.util.Try
Expand Down Expand Up @@ -305,17 +306,18 @@ class SpecificFileToFileSpec extends Specification {
val outDir = gen.defaultOutputDir + s"/specific/$unionType"
gen.fileToFile(inOrderSchema, outDir)

val classes = List(
Result.forall(List(
"UnionOfOneNonNullType",
"UnionOfNullWithOneNonNullType",
"UnionOfTwoNonNullTypes",
"UnionOfNullWithTwoNonNullTypes",
"UnionOfMoreThanTwoNonNullTypes",
"UnionOfNullWithMoreThanTwoNonNullTypes"
)
val sources = classes.map(className => util.Util.readFile(s"avrohugger-core/src/test/expected/specific/$unionType/com/example/avrohugger/unions_with_coproduct_avsc2/$className.scala"))
)) { className =>

Result.forall(classes.zip(sources)) { case (className, expect) =>
util.Util.readFile(s"target/generated-sources/specific/$unionType/com/example/avrohugger/unions_with_coproduct_avsc2/$className.scala") === expect
val generatedFile = s"target/generated-sources/specific/$unionType/com/example/avrohugger/unions_with_coproduct_avsc2/$className.scala"
val expectationFile = s"avrohugger-core/src/test/expected/specific/$unionType/com/example/avrohugger/unions_with_coproduct_avsc2/$className.scala"
generatedFile must containExpectedContentIn(expectationFile)
}
}

Expand Down
8 changes: 8 additions & 0 deletions avrohugger-core/src/test/scala/util/Util.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package util

import org.specs2.matcher.{Expectable, MatchResult, Matcher}

object Util {

def readFile(fileName: String, maxTries: Int = 3): String = {
Expand All @@ -26,4 +28,10 @@ object Util {
case e: Throwable => false
}

def containExpectedContentIn(expectPath: String): Matcher[String] = new Matcher[String] {
override def apply[S <: String](t: Expectable[S]): MatchResult[S] = {
val generatedPath = t.value
result(readFile(generatedPath) == readFile(expectPath), s"$generatedPath === $expectPath", s"\ndiff -ruBbE $expectPath $generatedPath", t)
}
}
}
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ lazy val avroVersion = "1.11.3"

lazy val commonSettings = Seq(
organization := "com.julianpeeters",
version := "1.5.5",
version := "1.5.6",
ThisBuild / versionScheme := Some("semver-spec"),
scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature"),
Test / scalacOptions ++= Seq("-Yrangepos"),
Expand Down

0 comments on commit 68aa44d

Please sign in to comment.