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 Refined module #33

Open
wants to merge 2 commits 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
30 changes: 22 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import sbt.Keys._
lazy val buildSettings = Seq(
organization := "com.github.melrief",
scalaVersion := "2.12.1",
crossScalaVersions := Seq("2.10.5", "2.11.8", "2.12.1")
crossScalaVersions := Seq("2.10.5", "2.11.8", "2.12.1"),
javacOptions ++= Seq("-source", "1.8", "-target", "1.8"),
scalacOptions ++= Seq("-feature", "-deprecation")
)

lazy val publishSettings = Seq(
Expand Down Expand Up @@ -44,19 +46,15 @@ lazy val noPublishSettings = Seq(
)

lazy val root = project.in(file(".")).
aggregate(pureCSVJVM, pureCSVJS).
aggregate(pureCSVJVM, pureCSVJS, refinedJVM, refinedJS).
settings(buildSettings).
settings(publishSettings).
settings(noPublishSettings)
settings(publishSettings)

lazy val pureCSV = crossProject.crossType(CrossType.Full).in(new File(".")).
lazy val pureCSV = crossProject.crossType(CrossType.Full).in(file("purecsv")).
settings(buildSettings).
settings(publishSettings).
settings(
name := "purecsv",
version := "0.1.1",
javacOptions ++= Seq("-source", "1.8", "-target", "1.8"),
scalacOptions ++= Seq("-feature", "-deprecation"),
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.2",
compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
Expand All @@ -76,3 +74,19 @@ lazy val pureCSV = crossProject.crossType(CrossType.Full).in(new File(".")).

lazy val pureCSVJVM = pureCSV.jvm
lazy val pureCSVJS = pureCSV.js

lazy val refined = (crossProject.crossType(CrossType.Full) in file("modules/refined")).
dependsOn(pureCSV).
dependsOn(pureCSV % "test->test").
settings(buildSettings).
settings(publishSettings).
settings(
name := "purecsv-refined",
libraryDependencies ++= Seq(
"eu.timepit" %% "refined" % "0.8.4")
).
jvmSettings().
jsSettings()

lazy val refinedJVM = refined.jvm
lazy val refinedJS = refined.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package purecsv.module.refined

import scala.language.higherKinds
import scala.util.{Failure, Success, Try}

import eu.timepit.refined.api.{RefType, Validate}

import purecsv.safe.converter.StringConverter

/**
* StringConverter instance for refined types
*/
package object safe {

implicit def refinedConverter[R[_, _], T, P](implicit
baseConverter: StringConverter[T],
reftype: RefType[R],
validate: Validate[T, P]) = new StringConverter[R[T, P]] {

override def tryFrom(str: String): Try[R[T, P]] = {
baseConverter.tryFrom(str).flatMap { t =>
reftype.refine[P](t) match {
case Left(errors) => Failure(new IllegalArgumentException(errors))
case Right(refinedValue) => Success(refinedValue)
}
}
}

override def to(value: R[T, P]): String = {
baseConverter.to(reftype.unwrap(value))
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package purecsv.module.refined

import scala.language.higherKinds

import eu.timepit.refined.api.{RefType, Validate}
import purecsv.unsafe.converter.StringConverter

package object unsafe {

implicit def refinedConverter[R[_, _], T, P](implicit
baseConverter: StringConverter[T],
reftype: RefType[R],
validate: Validate[T, P]) = new StringConverter[R[T, P]] {

override def from(str: String): R[T, P] = {
val baseValue = baseConverter.from(str)
reftype.refine[P](baseValue) match {
case Left(errors) => throw new IllegalArgumentException(errors)
case Right(refinedValue) => refinedValue
}
}

override def to(value: R[T, P]): String = {
baseConverter.to(reftype.unwrap(value))
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package purecsv.modules.refined.safe

import scala.util.Success

import eu.timepit.refined.auto._
import eu.timepit.refined.types.numeric.PosInt
import org.scalatest.{FunSuite, Matchers}
import purecsv.safe._
import purecsv.safe.converter.StringConverter
import purecsv.module.refined.safe._

class RefinedSafeSuite extends FunSuite with Matchers {

test("Reading a refined type works") {
val posOne: PosInt = 1
StringConverter[PosInt].tryFrom("1") should be (Success(posOne))
StringConverter[PosInt].tryFrom("-4") should be a 'failure
}

test("Writing a refined type works") {
val posOne: PosInt = 1
StringConverter[PosInt].to(posOne) should be ("1")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package purecsv.modules.refined.unsafe

import eu.timepit.refined.auto._
import eu.timepit.refined.types.numeric.PosInt
import org.scalatest.{FunSuite, Matchers}
import purecsv.unsafe._
import purecsv.unsafe.converter.StringConverter
import purecsv.module.refined.unsafe._

class RefinedUnsafeSuite extends FunSuite with Matchers {

test("Reading a refined type works") {
val posOne: PosInt = 1
StringConverter[PosInt].from("1") should be (posOne)

an [IllegalArgumentException] should be thrownBy
StringConverter[PosInt].from("-4")
}

test("Writing a refined type works") {
val posOne: PosInt = 1
StringConverter[PosInt].to(posOne) should be ("1")
}

}
1 change: 1 addition & 0 deletions version.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version in ThisBuild := "0.1.1"