Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vulcan avro integration #418

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
run: sbt ++${{ matrix.scala }} test

- name: Compress target directories
run: tar cf targets.tar modules/tests/target modules/tethys/target modules/pureconfig/target modules/catsTagless/target modules/ciris/target modules/scalacheck/target modules/circeMagnolia/target modules/circe/target target modules/tethysMagnolia/target modules/cats/target modules/core/target modules/sangria/target modules/reactivemongo/target project/target
run: tar cf targets.tar modules/tests/target modules/tethys/target modules/pureconfig/target modules/catsTagless/target modules/ciris/target modules/scalacheck/target modules/circeMagnolia/target modules/circe/target target modules/tethysMagnolia/target modules/cats/target modules/core/target modules/vulcan/target modules/sangria/target modules/reactivemongo/target project/target

- name: Upload target directories
uses: actions/upload-artifact@v2
Expand Down
10 changes: 10 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ lazy val derevo = project
tethys,
tethysMagnolia,
sangria,
vulcan,
tests,
)

Expand Down Expand Up @@ -164,6 +165,15 @@ lazy val sangria =
)
.dependsOn(core)

lazy val vulcan =
(project in file("modules/vulcan"))
.settings(publishSettings)
.settings(
name := "derevo-vulcan",
libraryDependencies ++= Seq(Dependencies.vulcanGeneric),
)
.dependsOn(core)

lazy val tests =
(project in file("modules/tests"))
.settings(noPublishSettings)
Expand Down
18 changes: 18 additions & 0 deletions modules/vulcan/src/main/scala/derevo/vulcan/avroCodec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package derevo.vulcan

import derevo.{Derivation, NewTypeDerivation}
import magnolia.{CaseClass, Magnolia, SealedTrait}
import vulcan.Codec
import vulcan.generic._

object avroCodec extends Derivation[Codec] with NewTypeDerivation[Codec] {

type Typeclass[A] = Codec[A]

def combine[A](caseClass: CaseClass[Codec, A]): Codec[A] = Codec.combine(caseClass)

def dispatch[A](sealedTrait: SealedTrait[Codec, A]): Codec.Aux[Any, A] = Codec.dispatch(sealedTrait)

def instance[A]: Codec[A] = macro Magnolia.gen[A]

}
37 changes: 37 additions & 0 deletions modules/vulcan/src/test/scala/derevo/vulcan/AvroCodecTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package derevo.vulcan

import org.apache.avro.Schema
import derevo.derive
import org.scalatest.Assertion
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import vulcan.Codec
import vulcan.generic.{AvroDoc, AvroName}

import java.time.Instant

@derive(avroCodec)
case class Foo(i: Int, s: String, bar: Bar)

@derive(avroCodec)
case class Bar(
@AvroName("time_dttm") @AvroDoc("Timestamp")
timestamp: Instant,
@AvroName("int_list") @AvroDoc("List of ints")
intList: List[Int]
)

class AvroCodecTest extends AnyFlatSpec with Matchers {

val fooSchema: String =
"""{"type":"record","name":"Foo","namespace":"derevo.vulcan","fields":[{"name":"i","type":"int"},{"name":"s","type":"string"},{"name":"bar","type":{"type":"record","name":"Bar","fields":[{"name":"time_dttm","type":{"type":"long","logicalType":"timestamp-millis"},"doc":"Timestamp"},{"name":"int_list","type":{"type":"array","items":"int"},"doc":"List of ints"}]}}]}"""

def assertSchema[A: Codec](schemaStr: String): Assertion = {
val expectedSchema = new Schema.Parser().parse(schemaStr.mkString.trim)
Codec[A].schema shouldBe Right(expectedSchema)
}

"Writer derivation for ADT" should "work correctly" in {
assertSchema[Foo](fooSchema)
}
}
4 changes: 4 additions & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ object Dependencies {
val macroParadise = "2.1.1"

val sangria = "3.2.0"

val vulcan = "1.10.1"
}

lazy val magnolia = "com.propensive" %% "magnolia" % Version.magnolia
Expand All @@ -66,6 +68,8 @@ object Dependencies {
lazy val estatico = "io.estatico" %% "newtype" % Version.estatico
lazy val supertagged = "org.rudogma" %% "supertagged" % Version.supertagged

lazy val vulcanGeneric = "com.github.fd4s" %% "vulcan-generic" % Version.vulcan

lazy val macroParadise = "org.scalamacros" % "paradise" % Version.macroParadise cross CrossVersion.patch
lazy val kindProjector = "org.typelevel" %% "kind-projector" % Version.kindProjector cross CrossVersion.patch

Expand Down