-
Notifications
You must be signed in to change notification settings - Fork 149
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 enumeratum-quill #170
Merged
Merged
Add enumeratum-quill #170
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
e621892
Add enumeratum-quill
daniel-shuy c23dbd9
Improve QuillEnumSpec and QuillValueEnumSpec
daniel-shuy 1d89916
Add tests for LongEnum, ShortEnum, StringEnum, CharEnum, ByteEnum
daniel-shuy 77d51f6
Encode/Decode CharEnum from/to String instead
daniel-shuy d0340fd
Improve Quill Integration examples in README
daniel-shuy 8a62517
Add note on quill-cassandra and quill-orientdb in README
daniel-shuy dd394aa
Merge branch 'master' into master
daniel-shuy 16869e1
Fix Quill Issue links
daniel-shuy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ lazy val circeVersion = "0.9.0" | |
lazy val uPickleVersion = "0.4.4" | ||
lazy val argonautVersion = "6.2" | ||
lazy val json4sVersion = "3.5.1" | ||
lazy val quillVersion = "2.3.2" | ||
|
||
def thePlayVersion(scalaVersion: String) = | ||
CrossVersion.partialVersion(scalaVersion) match { | ||
|
@@ -320,6 +321,33 @@ lazy val enumeratumScalacheck = crossProject | |
lazy val enumeratumScalacheckJs = enumeratumScalacheck.js | ||
lazy val enumeratumScalacheckJvm = enumeratumScalacheck.jvm | ||
|
||
lazy val quillAggregate = aggregateProject("quill", enumeratumQuillJs, enumeratumQuillJvm) | ||
lazy val enumeratumQuill = crossProject | ||
.crossType(CrossType.Pure) | ||
.in(file("enumeratum-quill")) | ||
.settings(commonWithPublishSettings: _*) | ||
.settings(testSettings: _*) | ||
.settings( | ||
name := "enumeratum-quill", | ||
version := "0.1.0-SNAPSHOT", | ||
libraryDependencies ++= { | ||
import org.scalajs.sbtplugin._ | ||
val cross = { | ||
if (ScalaJSPlugin.autoImport.jsDependencies.?.value.isDefined) | ||
ScalaJSCrossVersion.binary | ||
else | ||
CrossVersion.binary | ||
} | ||
Seq( | ||
impl.ScalaJSGroupID.withCross("io.getquill", "quill-core", cross) % quillVersion, | ||
impl.ScalaJSGroupID.withCross("io.getquill", "quill-sql", cross) % quillVersion % Test, | ||
impl.ScalaJSGroupID.withCross("com.beachape", "enumeratum", cross) % Versions.Core.stable | ||
) | ||
} | ||
) | ||
lazy val enumeratumQuillJs = enumeratumQuill.js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL: Quill works with ScalaJS O_o There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haha I was shocked as well |
||
lazy val enumeratumQuillJvm = enumeratumQuill.jvm | ||
|
||
lazy val commonSettings = Seq( | ||
organization := "com.beachape", | ||
scalafmtOnCompile := true, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package enumeratum | ||
|
||
import io.getquill.MappedEncoding | ||
|
||
object Quill { | ||
/** | ||
* Returns an Encoder for the given enum | ||
*/ | ||
def encoder[A <: EnumEntry](enum: Enum[A]): MappedEncoding[A, String] = MappedEncoding(_.entryName) | ||
|
||
/** | ||
* Returns a Decoder for the given enum | ||
*/ | ||
def decoder[A <: EnumEntry](enum: Enum[A]): MappedEncoding[String, A] = MappedEncoding(enum.withName) | ||
} |
45 changes: 45 additions & 0 deletions
45
enumeratum-quill/src/main/scala/enumeratum/QuillEnum.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package enumeratum | ||
|
||
import io.getquill.MappedEncoding | ||
|
||
/** | ||
* Helper trait that adds implicit Quill encoders and decoders for an [[Enum]]'s members | ||
* | ||
* Example: | ||
* | ||
* {{{ | ||
* scala> import enumeratum._ | ||
* scala> import io.getquill._ | ||
* | ||
* scala> sealed trait ShirtSize extends EnumEntry | ||
* scala> case object ShirtSize extends Enum[ShirtSize] with QuillEnum[ShirtSize] { | ||
* | case object Small extends ShirtSize | ||
* | case object Medium extends ShirtSize | ||
* | case object Large extends ShirtSize | ||
* | val values = findValues | ||
* | } | ||
* | ||
* scala> case class Shirt(size: ShirtSize) | ||
* | ||
* scala> val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal) | ||
* scala> import ctx._ | ||
* | ||
* scala> val size: ShirtSize = ShirtSize.Small | ||
* | ||
* scala> ctx.run(query[Shirt].insert(_.size -> lift(size))).string | ||
* res0: String = INSERT INTO Shirt (size) VALUES (?) | ||
* }}} | ||
*/ | ||
trait QuillEnum[A <: EnumEntry] { this: Enum[A] => | ||
|
||
/** | ||
* Implicit Encoder for this enum | ||
*/ | ||
implicit lazy val enumEncoder: MappedEncoding[A, String] = Quill.encoder(this) | ||
|
||
/** | ||
* Implicit Decoder for this enum | ||
*/ | ||
implicit lazy val enumDecoder: MappedEncoding[String, A] = Quill.decoder(this) | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
enumeratum-quill/src/main/scala/enumeratum/values/Quill.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package enumeratum.values | ||
|
||
import io.getquill.MappedEncoding | ||
|
||
object Quill { | ||
|
||
/** | ||
* Returns an Encoder for the provided ValueEnum | ||
*/ | ||
def encoder[ValueType, EntryType <: ValueEnumEntry[ValueType]]( | ||
enum: ValueEnum[ValueType, EntryType] | ||
): MappedEncoding[EntryType, ValueType] = MappedEncoding(_.value) | ||
|
||
/** | ||
* Returns a Decoder for the provided ValueEnum | ||
*/ | ||
def decoder[ValueType, EntryType <: ValueEnumEntry[ValueType]]( | ||
enum: ValueEnum[ValueType, EntryType] | ||
): MappedEncoding[ValueType, EntryType] = MappedEncoding(enum.withValue) | ||
} |
102 changes: 102 additions & 0 deletions
102
enumeratum-quill/src/main/scala/enumeratum/values/QuillValueEnum.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package enumeratum.values | ||
|
||
import io.getquill.MappedEncoding | ||
|
||
sealed trait QuillValueEnum[ValueType, EntryType <: ValueEnumEntry[ValueType], QuillType] { | ||
this: ValueEnum[ValueType, EntryType] => | ||
|
||
/** | ||
* Implicit Encoder for this enum | ||
*/ | ||
implicit val quillEncoder: MappedEncoding[EntryType, QuillType] | ||
|
||
/** | ||
* Implicit Decoder for this enum | ||
*/ | ||
implicit val quillDecoder: MappedEncoding[QuillType, EntryType] | ||
} | ||
|
||
/** | ||
* QuillEnum for IntEnumEntry | ||
* | ||
* {{{ | ||
* scala> import enumeratum.values._ | ||
* scala> import io.getquill._ | ||
* | ||
* scala> sealed abstract class ShirtSize(val value:Int) extends IntEnumEntry | ||
* scala> case object ShirtSize extends IntEnum[ShirtSize] with IntQuillEnum[ShirtSize] { | ||
* | case object Small extends ShirtSize(1) | ||
* | case object Medium extends ShirtSize(2) | ||
* | case object Large extends ShirtSize(3) | ||
* | val values = findValues | ||
* | } | ||
* | ||
* scala> case class Shirt(size: ShirtSize) | ||
* | ||
* scala> val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal) | ||
* scala> import ctx._ | ||
* | ||
* scala> val size: ShirtSize = ShirtSize.Small | ||
* | ||
* scala> ctx.run(query[Shirt].insert(_.size -> lift(size))).string | ||
* res0: String = INSERT INTO Shirt (size) VALUES (?) | ||
* }}} | ||
*/ | ||
trait IntQuillEnum[EntryType <: IntEnumEntry] extends QuillValueEnum[Int, EntryType, Int] { | ||
this: ValueEnum[Int, EntryType] => | ||
implicit val quillEncoder: MappedEncoding[EntryType, Int] = Quill.encoder(this) | ||
implicit val quillDecoder: MappedEncoding[Int, EntryType] = Quill.decoder(this) | ||
} | ||
|
||
/** | ||
* QuillEnum for LongEnumEntry | ||
*/ | ||
trait LongQuillEnum[EntryType <: LongEnumEntry] extends QuillValueEnum[Long, EntryType, Long] { | ||
this: ValueEnum[Long, EntryType] => | ||
implicit val quillEncoder: MappedEncoding[EntryType, Long] = Quill.encoder(this) | ||
implicit val quillDecoder: MappedEncoding[Long, EntryType] = Quill.decoder(this) | ||
} | ||
|
||
/** | ||
* QuillEnum for ShortEnumEntry | ||
*/ | ||
trait ShortQuillEnum[EntryType <: ShortEnumEntry] extends QuillValueEnum[Short, EntryType, Short] { | ||
this: ValueEnum[Short, EntryType] => | ||
implicit val quillEncoder: MappedEncoding[EntryType, Short] = Quill.encoder(this) | ||
implicit val quillDecoder: MappedEncoding[Short, EntryType] = Quill.decoder(this) | ||
} | ||
|
||
/** | ||
* QuillEnum for StringEnumEntry | ||
*/ | ||
trait StringQuillEnum[EntryType <: StringEnumEntry] extends QuillValueEnum[String, EntryType, String] { | ||
this: ValueEnum[String, EntryType] => | ||
implicit val quillEncoder: MappedEncoding[EntryType, String] = Quill.encoder(this) | ||
implicit val quillDecoder: MappedEncoding[String, EntryType] = Quill.decoder(this) | ||
} | ||
|
||
/** | ||
* QuillEnum for CharEnumEntry | ||
*/ | ||
trait CharQuillEnum[EntryType <: CharEnumEntry] extends QuillValueEnum[Char, EntryType, String] { | ||
this: ValueEnum[Char, EntryType] => | ||
|
||
/** | ||
* Because all existing Quill contexts do not have built-in Encoders for Char, convert it to a String instead. | ||
*/ | ||
implicit val quillEncoder: MappedEncoding[EntryType, String] = MappedEncoding(enum => String.valueOf(enum.value)) | ||
|
||
/** | ||
* Because all existing Quill contexts do not have built-in Decoders for Char, convert it from a String instead. | ||
*/ | ||
implicit val quillDecoder: MappedEncoding[String, EntryType] = MappedEncoding(str => withValue(str.charAt(0))) | ||
} | ||
|
||
/** | ||
* QuillEnum for ByteEnumEntry | ||
*/ | ||
trait ByteQuillEnum[EntryType <: ByteEnumEntry] extends QuillValueEnum[Byte, EntryType, Byte] { | ||
this: ValueEnum[Byte, EntryType] => | ||
implicit val quillEncoder: MappedEncoding[EntryType, Byte] = Quill.encoder(this) | ||
implicit val quillDecoder: MappedEncoding[Byte, EntryType] = Quill.decoder(this) | ||
} |
47 changes: 47 additions & 0 deletions
47
enumeratum-quill/src/test/scala/enumeratum/QuillEnumSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package enumeratum | ||
|
||
import org.scalatest.{FunSpec, Matchers} | ||
|
||
import scala.collection.immutable | ||
|
||
class QuillEnumSpec extends FunSpec with Matchers { | ||
|
||
describe("A QuillEnum") { | ||
|
||
// we only need to test whether it can compile because Quill will fail compilation if an Encoder is not found | ||
it("should encode to String") { | ||
""" | ||
| import io.getquill._ | ||
| val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal) | ||
| import ctx._ | ||
| ctx.run(query[QuillShirt].insert(_.size -> lift(QuillShirtSize.Small: QuillShirtSize))) | ||
""".stripMargin should compile | ||
} | ||
|
||
// we only need to test whether it can compile because Quill will fail compilation if a Decoder is not found | ||
it("should decode from String") { | ||
""" | ||
| import io.getquill._ | ||
| val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal) | ||
| import ctx._ | ||
| ctx.run(query[QuillShirt]) | ||
""".stripMargin should compile | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
sealed trait QuillShirtSize extends EnumEntry | ||
|
||
case object QuillShirtSize extends Enum[QuillShirtSize] with QuillEnum[QuillShirtSize] { | ||
|
||
case object Small extends QuillShirtSize | ||
case object Medium extends QuillShirtSize | ||
case object Large extends QuillShirtSize | ||
|
||
override val values: immutable.IndexedSeq[QuillShirtSize] = findValues | ||
|
||
} | ||
|
||
case class QuillShirt(size: QuillShirtSize) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No big deal; but this isn't an explicit cast; just an explicit type annotation :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I knew that it wasn't an explicit cast (
asInstanceOf
), but I forgot what it was called, thanksThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, if we were to be pedantic, I guess this should be called a Type Ascription instead of a Type Annotation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, you missed out on one of the "explicit cast"s. I've opened a PR (#172) to fix both.