Skip to content

Conversation

@aborg0
Copy link
Owner

@aborg0 aborg0 commented Jun 14, 2018

Below is the output of the updated tut/Examples.md output (check the second part!):

Examples

Intro

There might be multiple implementations of ParseCaseClass, currently only RegexParseCaseClass and FastParseParseCaseClass are supported, but only one should be used in a scope (in this case RegexParseCaseClass):

import com.github.aborg0.caseyclassy.RegexParseCaseClass
import com.github.aborg0.caseyclassy.RegexParseCaseClass._
import java.time.{LocalDate, LocalTime}
import shapeless._

It is possible to parse simple values, like Boolean, Byte, Short, Int, Long, Float, Double, LocalTime, LocalDate and Strings without comma (,) or closing parenthesis ()), but this library was designed to parse toString of algebraic data types (products -case classes, tuples- and coproducts) of them. Also some Seqs (List, Vector, WrappedArray (for varargs)) are supported.

Simple primitives

LocalDate:

scala> val date: LocalDate = RegexParseCaseClass.to[LocalDate]("2018-04-01")
date: java.time.LocalDate = 2018-04-01

or it is also possible to create a parser and reuse it:

scala> val dateParser = RegexParseCaseClass[LocalDate]
dateParser: com.github.aborg0.caseyclassy.RegexParse[java.time.LocalDate] = com.github.aborg0.caseyclassy.RegexParseCaseClass$$anon$11@602995d3

scala> dateParser.parse("2018-04-01")
res0: java.time.LocalDate = 2018-04-01

scala> dateParser.parse("2018-04-22")
res1: java.time.LocalDate = 2018-04-22

Tuple2 of String and Int:

scala> RegexParseCaseClass.to[(String, Int)]("(   hello,4)")
res2: (String, Int) = ("   hello",4)

Or in the other order:

scala> val (i, s) = RegexParseCaseClass.to[(Int, String)]("(4,   hello)")
i: Int = 4
s: String = "   hello"

The error messages are not very good:

scala> val dateTuple1 = RegexParseCaseClass.to[Tuple1[LocalDate]]("2018-04-01")
java.lang.IllegalArgumentException: |018-04-0| does not start with proper value
  at com.github.aborg0.caseyclassy.CommonRegexParse.$anonfun$parse$6(RegexParseCaseClass.scala:183)
  at scala.Option.getOrElse(Option.scala:121)
  at com.github.aborg0.caseyclassy.CommonRegexParse.parse(RegexParseCaseClass.scala:183)
  at com.github.aborg0.caseyclassy.CommonRegexParse.parse$(RegexParseCaseClass.scala:182)
  at com.github.aborg0.caseyclassy.RegexParseCaseClass$$anon$11.parse(RegexParseCaseClass.scala:145)
  at com.github.aborg0.caseyclassy.GenericImplementations$$anon$2.parse(RegexParseCaseClass.scala:62)
  at com.github.aborg0.caseyclassy.GenericImplementations$$anon$2.parse(RegexParseCaseClass.scala:51)
  at com.github.aborg0.caseyclassy.GenericImplementations$$anon$4.parse(RegexParseCaseClass.scala:114)
  at com.github.aborg0.caseyclassy.RegexParseCaseClass$.to(RegexParseCaseClass.scala:130)
  ... 43 elided

Algebraic data types

With help of shapeless the following constructs are supported:

  • case classes
  • case objects
  • sealed hierarchies
  • tuples
  • a few Seq types

Case classes

scala> case class Example(a: Int, s: String)
defined class Example

scala> RegexParseCaseClass.to[Example]("Example(-3, Hello)")
res3: Example = Example(-3, Hello)
scala> case object Dot
defined object Dot

scala> RegexParseCaseClass.to[Dot.type]("Dot")
res4: Dot.type = Dot

Sealed hierarchies

Either

scala> RegexParseCaseClass.to[Either[Short, Boolean]]("Left(-1111)")
res5: Either[Short,Boolean] = Left(-1111)

scala> RegexParseCaseClass.to[Either[Short, Boolean]]("Right(false)")
res6: Either[Short,Boolean] = Right(false)

Option

scala> RegexParseCaseClass.to[Option[Option[Int]]]("Some(None)")
res7: Option[Option[Int]] = Some(None)

scala> RegexParseCaseClass.to[Option[Option[Int]]]("None")
res8: Option[Option[Int]] = None

scala> RegexParseCaseClass.to[Option[Either[String, Seq[Boolean]]]]("Some(Right(List()))")
res9: Option[Either[String,Seq[Boolean]]] = Some(Right(Vector()))

scala> RegexParseCaseClass.to[Option[Either[String, Seq[Boolean]]]]("Some(Right(List(false, true)))")
res10: Option[Either[String,Seq[Boolean]]] = Some(Right(Vector(false, true)))

Limitations

String handling is not ideal:

scala> RegexParseCaseClass.to[Option[Either[String, Seq[Boolean]]]]("Some(Left(List(false, true)))")
res11: Option[Either[String,Seq[Boolean]]] = Some(Left(List(false))

Please note that the String part contains only till the first , (List(false) within and no error is reported currently.

Same content with FastParse (FastParseParseCaseClass)

Intro

There might be multiple implementations of ParseCaseClass, currently only RegexParseCaseClass and FastParseParseCaseClass are supported, but only one should be used in a scope (in this case FastParseParseCaseClass):

import com.github.aborg0.caseyclassy.FastParseParseCaseClass
import com.github.aborg0.caseyclassy.FastParseParseCaseClass._
import java.time.{LocalDate, LocalTime}
import shapeless._

It is possible to parse simple values, like Boolean, Byte, Short, Int, Long, Float, Double, LocalTime, LocalDate and Strings without comma (,) or closing parenthesis ()), but this library was designed to parse toString of algebraic data types (products -case classes, tuples- and coproducts) of them. Also some Seqs (List, Vector, WrappedArray (for varargs)) are supported.

Simple primitives

LocalDate:

scala> val date: LocalDate = FastParseParseCaseClass.to[LocalDate]("2018-04-01")
date: java.time.LocalDate = 2018-04-01

or it is also possible to create a parser and reuse it:

scala> val dateParser = FastParseParseCaseClass[LocalDate]
dateParser: com.github.aborg0.caseyclassy.FastParseParse[java.time.LocalDate] = com.github.aborg0.caseyclassy.FastParseParseCaseClass$$anonfun$dateParse$4@66ec5b45

scala> dateParser.parse("2018-04-01")
res0: java.time.LocalDate = 2018-04-01

scala> dateParser.parse("2018-04-22")
res1: java.time.LocalDate = 2018-04-22

Tuple2 of String and Int:

scala> FastParseParseCaseClass.to[(String, Int)]("(   hello,4)")
res2: (String, Int) = ("   hello",4)

Or in the other order:

scala> val (i, s) = FastParseParseCaseClass.to[(Int, String)]("(4,   hello)")
i: Int = 4
s: String = "   hello"

The error messages are not very good:

scala> val dateTuple1 = FastParseParseCaseClass.to[Tuple1[LocalDate]]("2018-04-01")
java.lang.IllegalArgumentException: Expected: "(" at position: 0
  at com.github.aborg0.caseyclassy.FastParseParse.$anonfun$parse$1(FastParseParseCaseClass.scala:88)
  at com.github.aborg0.caseyclassy.FastParseParse.$anonfun$parse$1$adapted(FastParseParseCaseClass.scala:87)
  at fastparse.core.Parsed.fold(Parsing.scala:40)
  at fastparse.core.Parsed.fold$(Parsing.scala:38)
  at fastparse.core.Parsed$Failure.fold(Parsing.scala:74)
  at com.github.aborg0.caseyclassy.FastParseParse.parse(FastParseParseCaseClass.scala:88)
  at com.github.aborg0.caseyclassy.FastParseParse.parse$(FastParseParseCaseClass.scala:87)
  at com.github.aborg0.caseyclassy.FPGenericImplementations$$anonfun$generic$10.parse(FastParseParseCaseClass.scala:44)
  at com.github.aborg0.caseyclassy.FastParseParseCaseClass$.to(FastParseParseCaseClass.scala:59)
  ... 43 elided

Algebraic data types

With help of shapeless the following constructs are supported:

  • case classes
  • case objects
  • sealed hierarchies
  • tuples
  • a few Seq types

Case classes

scala> case class Example(a: Int, s: String)
defined class Example

scala> FastParseParseCaseClass.to[Example]("Example(-3, Hello)")
res3: Example = Example(-3, Hello)
scala> case object Dot
defined object Dot

scala> FastParseParseCaseClass.to[Dot.type]("Dot")
res4: Dot.type = Dot

Sealed hierarchies

Either

scala> FastParseParseCaseClass.to[Either[Short, Boolean]]("Left(-1111)")
res5: Either[Short,Boolean] = Left(-1111)

scala> FastParseParseCaseClass.to[Either[Short, Boolean]]("Right(false)")
res6: Either[Short,Boolean] = Right(false)

Option

scala> FastParseParseCaseClass.to[Option[Option[Int]]]("Some(None)")
res7: Option[Option[Int]] = Some(None)

scala> FastParseParseCaseClass.to[Option[Option[Int]]]("None")
res8: Option[Option[Int]] = None

scala> FastParseParseCaseClass.to[Option[Either[String, Seq[Boolean]]]]("Some(Right(List()))")
res9: Option[Either[String,Seq[Boolean]]] = Some(Right(ArrayBuffer()))

scala> FastParseParseCaseClass.to[Option[Either[String, Seq[Boolean]]]]("Some(Right(List(false, true)))")
res10: Option[Either[String,Seq[Boolean]]] = Some(Right(ArrayBuffer(false, true)))

@coveralls
Copy link

Pull Request Test Coverage Report for Build 26

  • 35 of 36 (97.22%) changed or added relevant lines in 1 file are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage decreased (-0.2%) to 94.872%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/main/scala/com/github/aborg0/caseyclassy/FastParseParseCaseClass.scala 35 36 97.22%
Files with Coverage Reduction New Missed Lines %
src/main/scala/com/github/aborg0/caseyclassy/RegexParseCaseClass.scala 1 93.83%
Totals Coverage Status
Change from base Build 22: -0.2%
Covered Lines: 111
Relevant Lines: 117

💛 - Coveralls

1 similar comment
@coveralls
Copy link

Pull Request Test Coverage Report for Build 26

  • 35 of 36 (97.22%) changed or added relevant lines in 1 file are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage decreased (-0.2%) to 94.872%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/main/scala/com/github/aborg0/caseyclassy/FastParseParseCaseClass.scala 35 36 97.22%
Files with Coverage Reduction New Missed Lines %
src/main/scala/com/github/aborg0/caseyclassy/RegexParseCaseClass.scala 1 93.83%
Totals Coverage Status
Change from base Build 22: -0.2%
Covered Lines: 111
Relevant Lines: 117

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants