Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created April 18, 2019 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yasuabe/647872e07439cc24d31ae7f82db4cca5 to your computer and use it in GitHub Desktop.
Save yasuabe/647872e07439cc24d31ae7f82db4cca5 to your computer and use it in GitHub Desktop.
squants exercise with Circe
package exercise.squants.with_circe
import eu.timepit.refined.types.string.NonEmptyString
import io.circe.parser.parse
import squants.market.{Money, Price}
import cats.syntax.either._
import io.circe.refined._
import io.circe._
import io.circe.generic.auto._
import squants.space.Volume
import cats.syntax.apply._
import cats.instances.try_._
import scala.util.{Failure, Try}
case class Order(
name: NonEmptyString,
quantity: Volume,
unitPrice: Price[Volume]
)
object Main {
def makeDecoder[A](f: String => Try[A]): Decoder[A] = Decoder.decodeString.emap {
f(_).toEither.leftMap(_.getMessage)
}
private val priceUnit = "([^/]*)/(.*)".r
implicit val volumeDecoder: Decoder[Volume] = makeDecoder(Volume(_))
implicit val priceDecoder: Decoder[Price[Volume]] = makeDecoder {
case priceUnit(p, u) => (Money(p), Volume(u)) mapN (_ / _)
case _ => Failure(new Exception("cannot parse unit price"))
}
val rawJson: String = """{
"name": "crude oil",
"quantity": "456 L",
"unitPrice": "64.39 USD/42 gal"
}
"""
def main(args: Array[String]): Unit = {
val result: Either[Error, Order] = parse(rawJson) flatMap (_.as[Order])
println(result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment