Skip to content
This repository has been archived by the owner on Mar 11, 2020. It is now read-only.

Commit

Permalink
A PR to add a fifth parameter to the spec was pushed earlier in the y…
Browse files Browse the repository at this point in the history
…ear but the actual mechanics in codecs and Remote weren't added - this adds them. Also, noticed a typo where refs weren't getting unioned correctly with parameters.
  • Loading branch information
sbuzzard committed Jun 30, 2016
1 parent df3aadb commit 1335abe
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 12 deletions.
28 changes: 22 additions & 6 deletions core/src/main/scala/Remote.scala
Expand Up @@ -85,6 +85,10 @@ object Remote {
def apply(a: Remote[A], b: Remote[B], c: Remote[C], d: Remote[D]): Remote[E] =
Remote.Ap4(self, a, b, c, d)
}
implicit class Ap5Syntax[A,B,C,D,E,F](self: Remote[(A,B,C,D,E) => F]) {
def apply(a: Remote[A], b: Remote[B], c: Remote[C], d: Remote[D], e: Remote[E]): Remote[F] =
Remote.Ap5(self, a, b, c, d, e)
}

/** Promote a local value to a remote value. */
private[remotely] case class Local[A](
Expand Down Expand Up @@ -134,24 +138,36 @@ object Remote {
override def toString = s"$f($a, $b, $c, $d)"
}

private[remotely] case class Ap5[A,B,C,D,E,F](
f: Remote[(A,B,C,D,E) => F],
a: Remote[A],
b: Remote[B],
c: Remote[C],
d: Remote[D],
e: Remote[E]) extends Remote[F] {
override def toString = s"$f($a, $b, $c, $d, $e)"
}

/** Collect up all the `Ref` names referenced by `r`. */
def refs[A](r: Remote[A]): SortedSet[String] = r match {
case Local(a,e,t) => SortedSet.empty
case Ref(t) => SortedSet(t)
case Ap1(f,a) => refs(f).union(refs(a))
case Ap2(f,a,b) => refs(f).union(refs(b)).union(refs(b))
case Ap3(f,a,b,c) => refs(f).union(refs(b)).union(refs(b)).union(refs(c))
case Ap4(f,a,b,c,d) => refs(f).union(refs(b)).union(refs(b)).union(refs(c)).union(refs(d))
case Ap2(f,a,b) => refs(f).union(refs(a)).union(refs(b))
case Ap3(f,a,b,c) => refs(f).union(refs(a)).union(refs(b)).union(refs(c))
case Ap4(f,a,b,c,d) => refs(f).union(refs(a)).union(refs(b)).union(refs(c)).union(refs(d))
case Ap5(f,a,b,c,d,e) => refs(f).union(refs(a)).union(refs(b)).union(refs(c)).union(refs(d)).union(refs(e))
}

/** Collect up all the formats referenced by `r`. */
def formats[A](r: Remote[A]): SortedSet[String] = r match {
case Local(a,e,t) => SortedSet(t)
case Ref(t) => SortedSet.empty
case Ap1(f,a) => formats(f).union(formats(a))
case Ap2(f,a,b) => formats(f).union(formats(b)).union(formats(b))
case Ap3(f,a,b,c) => formats(f).union(formats(b)).union(formats(b)).union(formats(c))
case Ap4(f,a,b,c,d) => formats(f).union(formats(b)).union(formats(b)).union(formats(c)).union(formats(d))
case Ap2(f,a,b) => formats(f).union(formats(a)).union(formats(b))
case Ap3(f,a,b,c) => formats(f).union(formats(a)).union(formats(b)).union(formats(c))
case Ap4(f,a,b,c,d) => formats(f).union(formats(a)).union(formats(b)).union(formats(c)).union(formats(d))
case Ap5(f,a,b,c,d,e) => formats(f).union(formats(a)).union(formats(b)).union(formats(c)).union(formats(d)).union(formats(e))
}

def toTag[A:TypeTag]: String = {
Expand Down
2 changes: 0 additions & 2 deletions core/src/main/scala/Response.scala
Expand Up @@ -183,9 +183,7 @@ object Response {
/** Add the given entries to the `header` of this `Context`, overwriting on collisions. */
def ++(kvs: Iterable[(String,String)]): Context = copy(header = header ++ kvs)
}

object Context {

/** The empty `Context`, contains an empty header and tracing stack. */
val empty = Context(Map(), List())
}
Expand Down
9 changes: 5 additions & 4 deletions core/src/main/scala/Server.scala
Expand Up @@ -46,8 +46,8 @@ object Server {

val DecodeResult((respEncoder,ctx,r), trailing) =
codecs.requestDecoder(env).decode(request).
fold(e => throw new Error(e.messageWithContext), identity)
fold(e => throw new Error(e.messageWithContext), identity)

val expected = Remote.refs(r)
val unknown = (expected -- env.values.keySet).toList
if (unknown.nonEmpty) { // fail fast if the Environment doesn't know about some referenced values
Expand Down Expand Up @@ -98,14 +98,15 @@ object Server {
case Ap2(Ref(f),a,b) => Monad[Response].tuple2(eval(env)(a), eval(env)(b)).flatMap{case (a,b) => env.values(f)(a,b)} .asInstanceOf[Response[A]]
case Ap3(Ref(f),a,b,c) => Monad[Response].tuple3(eval(env)(a), eval(env)(b), eval(env)(c)).flatMap{case (a,b,c) => env.values(f)(a,b,c)} .asInstanceOf[Response[A]]
case Ap4(Ref(f),a,b,c,d) => Monad[Response].tuple4(eval(env)(a), eval(env)(b), eval(env)(c), eval(env)(d)).flatMap{case (a,b,c,d) => env.values(f)(a,b,c,d)} .asInstanceOf[Response[A]]
case Ap5(Ref(f),a,b,c,d,e) => Monad[Response].tuple5(eval(env)(a), eval(env)(b), eval(env)(c), eval(env)(d), eval(env)(e)).flatMap{case (a,b,c,d,e) => env.values(f)(a,b,c,d,e)} .asInstanceOf[Response[A]]
case _ => Response.delay { sys.error("unable to interpret remote expression of form: " + r) }
}
}

private def toTask[A](att: Attempt[A]): Task[A] =
att.fold(e => Task.fail(new Error(e.messageWithContext)),
att.fold(e => Task.fail(new Error(e.messageWithContext)),
a => Task.now(a))

def fail(msg: String): Task[Nothing] = Task.fail(new Error(msg))

class Error(msg: String) extends Exception(msg)
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/scala/codecs/codecs.scala
Expand Up @@ -143,6 +143,8 @@ package object codecs extends lowerprioritycodecs {
remoteEncode(f) <+> remoteEncode(a) <+> remoteEncode(b) <+> remoteEncode(c)
case Ap4(f,a,b,c,d) => C.uint8.encode(5) <+>
remoteEncode(f) <+> remoteEncode(a) <+> remoteEncode(b) <+> remoteEncode(c) <+> remoteEncode(d)
case Ap5(f,a,b,c,d,e) => C.uint8.encode(6) <+>
remoteEncode(f) <+> remoteEncode(a) <+> remoteEncode(b) <+> remoteEncode(c) <+> remoteEncode(d) <+> remoteEncode(e)
}

private val E = Monad[Decoder]
Expand Down Expand Up @@ -180,6 +182,8 @@ package object codecs extends lowerprioritycodecs {
Ap3(f.asInstanceOf[Remote[(Any,Any,Any) => Any]],a,b,c))
case 5 => E.apply5(go,go,go,go,go)((f,a,b,c,d) =>
Ap4(f.asInstanceOf[Remote[(Any,Any,Any,Any) => Any]],a,b,c,d))
case 6 => E.apply6(go,go,go,go,go,go)((f,a,b,c,d,e) =>
Ap5(f.asInstanceOf[Remote[(Any,Any,Any,Any,Any) => Any]],a,b,c,d,e))
case t => fail(Err(s"[decoding] unknown tag byte: $t"))
}
}
Expand Down

0 comments on commit 1335abe

Please sign in to comment.