-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from scala-exercises/eval-32-compatibility-sca…
…lajs Evaluator Client compatibility with ScalaJS
- Loading branch information
Showing
21 changed files
with
276 additions
and
333 deletions.
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
File renamed without changes.
19 changes: 19 additions & 0 deletions
19
client/shared/src/main/scala/org/scalaexercises/evaluator/EvaluatorAPI.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,19 @@ | ||
/* | ||
* scala-exercises-evaluator-client | ||
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com> | ||
*/ | ||
|
||
package org.scalaexercises.evaluator | ||
|
||
import cats.free.Free | ||
import org.scalaexercises.evaluator.EvaluatorResponses.EvaluationResponse | ||
import org.scalaexercises.evaluator.free.algebra.EvaluatorOps | ||
|
||
class EvaluatorAPI[F[_]](url: String, authKey: String)( | ||
implicit O: EvaluatorOps[F]) { | ||
|
||
def evaluates(resolvers: List[String] = Nil, | ||
dependencies: List[Dependency] = Nil, | ||
code: String): Free[F, EvaluationResponse[EvalResponse]] = | ||
O.evaluates(url, authKey, resolvers, dependencies, code) | ||
} |
39 changes: 39 additions & 0 deletions
39
client/shared/src/main/scala/org/scalaexercises/evaluator/EvaluatorClient.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,39 @@ | ||
/* | ||
* scala-exercises-evaluator-client | ||
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com> | ||
*/ | ||
|
||
package org.scalaexercises.evaluator | ||
|
||
import cats.data.XorT | ||
import cats.~> | ||
import cats._, cats.std.all._ | ||
import org.scalaexercises.evaluator.EvaluatorResponses.{EvalIO, EvaluationException, EvaluationResponse, EvaluationResult} | ||
import org.scalaexercises.evaluator.free.algebra.EvaluatorOp | ||
|
||
import scala.concurrent.Future | ||
import scala.concurrent.ExecutionContext.Implicits.global | ||
|
||
class EvaluatorClient(url: String, authKey: String) { | ||
|
||
lazy val api: EvaluatorAPI[EvaluatorOp] = new EvaluatorAPI(url, authKey) | ||
|
||
} | ||
|
||
object EvaluatorClient { | ||
|
||
def apply(url: String, authKey: String) = | ||
new EvaluatorClient(url, authKey) | ||
|
||
implicit class EvaluationIOSyntaxXOR[A]( | ||
evalIO: EvalIO[EvaluationResponse[A]]) { | ||
|
||
def exec( | ||
implicit I: (EvaluatorOp ~> Future)): Future[EvaluationResponse[A]] = | ||
evalIO foldMap I | ||
|
||
def liftEvaluator: XorT[EvalIO, EvaluationException, EvaluationResult[A]] = | ||
XorT[EvalIO, EvaluationException, EvaluationResult[A]](evalIO) | ||
|
||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
client/shared/src/main/scala/org/scalaexercises/evaluator/EvaluatorResponses.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,69 @@ | ||
/* | ||
* scala-exercises-evaluator-client | ||
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com> | ||
*/ | ||
|
||
package org.scalaexercises.evaluator | ||
|
||
import cats.data.Xor | ||
import cats.free.Free | ||
import cats.syntax.xor._ | ||
import io.circe.Decoder | ||
import io.circe.parser._ | ||
import io.circe.generic.auto._ | ||
import org.scalaexercises.evaluator.free.algebra.EvaluatorOp | ||
|
||
import scala.concurrent.Future | ||
import scala.concurrent.ExecutionContext.Implicits.global | ||
|
||
import fr.hmil.roshttp.HttpResponse | ||
import fr.hmil.roshttp.HeaderMap | ||
|
||
object EvaluatorResponses { | ||
|
||
type EvalIO[A] = Free[EvaluatorOp, A] | ||
|
||
type EvaluationResponse[A] = EvaluationException Xor EvaluationResult[A] | ||
|
||
case class EvaluationResult[A](result: A, | ||
statusCode: Int, | ||
headers: Map[String, String]) | ||
|
||
sealed abstract class EvaluationException(msg: String, | ||
cause: Option[Throwable] = None) | ||
extends Throwable(msg) { | ||
cause foreach initCause | ||
} | ||
|
||
case class JsonParsingException(msg: String, json: String) | ||
extends EvaluationException(msg) | ||
|
||
case class UnexpectedException(msg: String) extends EvaluationException(msg) | ||
|
||
def toEntity[A](futureResponse: Future[HttpResponse])( | ||
implicit D: Decoder[A]): Future[EvaluationResponse[A]] = | ||
futureResponse map { | ||
case r if isSuccess(r.statusCode) ⇒ | ||
decode[A](r.body).fold( | ||
e ⇒ | ||
JsonParsingException(e.getMessage, r.body) | ||
.left[EvaluationResult[A]], | ||
result ⇒ | ||
Xor.Right( | ||
EvaluationResult(result, r.statusCode, r.headers.toLowerCase)) | ||
) | ||
case r ⇒ | ||
UnexpectedException( | ||
s"Failed invoking get with status : ${r.statusCode}, body : \n ${r.body}") | ||
.left[EvaluationResult[A]] | ||
} | ||
|
||
private[this] def isSuccess(statusCode: Int) = | ||
statusCode >= 200 && statusCode <= 299 | ||
|
||
implicit class HeadersLowerCase[A >: String](headers: HeaderMap[A]) { | ||
|
||
def toLowerCase: Map[String, A] = | ||
headers.iterator.map(t => (t._1.toLowerCase, t._2)).toList.toMap | ||
} | ||
} |
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
30 changes: 30 additions & 0 deletions
30
...nt/shared/src/main/scala/org/scalaexercises/evaluator/free/interpreters/Interpreter.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,30 @@ | ||
/* | ||
* scala-exercises-evaluator-client | ||
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com> | ||
*/ | ||
|
||
package org.scalaexercises.evaluator.free.interpreters | ||
|
||
import cats.~> | ||
import org.scalaexercises.evaluator.api.Evaluator | ||
import org.scalaexercises.evaluator.free.algebra.{Evaluates, EvaluatorOp} | ||
|
||
import scala.concurrent.Future | ||
|
||
trait Interpreter { | ||
|
||
/** | ||
* Lifts Evaluator Ops to an effect capturing Monad such as Task via natural transformations | ||
*/ | ||
implicit def evaluatorOpsInterpreter: EvaluatorOp ~> Future = | ||
new (EvaluatorOp ~> Future) { | ||
|
||
val evaluator = new Evaluator() | ||
|
||
def apply[A](fa: EvaluatorOp[A]): Future[A] = fa match { | ||
case Evaluates(url, authKey, resolvers, dependencies, code) ⇒ | ||
evaluator.eval(url, authKey, resolvers, dependencies, code) | ||
} | ||
|
||
} | ||
} |
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
43 changes: 43 additions & 0 deletions
43
client/shared/src/main/scala/org/scalaexercises/evaluator/http/HttpRequestBuilder.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,43 @@ | ||
/* | ||
* scala-exercises-evaluator-client | ||
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com> | ||
*/ | ||
|
||
package org.scalaexercises.evaluator.http | ||
|
||
import org.scalaexercises.evaluator.http.HttpClient._ | ||
|
||
import scala.concurrent.Future | ||
|
||
import fr.hmil.roshttp.{HttpRequest, Method, HttpResponse} | ||
import fr.hmil.roshttp.body.BodyPart | ||
|
||
import java.nio.ByteBuffer | ||
|
||
case class HttpRequestBuilder( | ||
url: String, | ||
httpVerb: String, | ||
headers: Headers = Map.empty[String, String], | ||
body: String = "" | ||
) { | ||
|
||
case class CirceJSONBody(value: String) extends BodyPart { | ||
override def contentType: String = s"application/json; charset=utf-8" | ||
|
||
override def content: ByteBuffer = ByteBuffer.wrap(value.getBytes("utf-8")) | ||
} | ||
|
||
def withHeaders(headers: Headers) = copy(headers = headers) | ||
|
||
def withBody(body: String) = copy(body = body) | ||
|
||
def run: Future[HttpResponse] = { | ||
|
||
val request = HttpRequest(url) | ||
.withMethod(Method(httpVerb)) | ||
.withHeader("content-type", "application/json") | ||
.withHeaders(headers.toList: _*) | ||
|
||
request.send(CirceJSONBody(body)) | ||
} | ||
} |
Oops, something went wrong.