forked from eigengo/akka-patterns
/
marshalling.scala
68 lines (52 loc) · 2.05 KB
/
marshalling.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package org.cakesolutions.akkapatterns.api
import cc.spray.typeconversion._
import net.liftweb.json._
import cc.spray.http.{HttpContent, ContentType}
import cc.spray.http.MediaTypes._
import net.liftweb.json.Serialization._
import cc.spray.http.ContentTypeRange
import java.util.UUID
trait Marshallers extends DefaultMarshallers {
this: LiftJSON =>
implicit def liftJsonMarshaller[A <: Product] = new SimpleMarshaller[A] {
val canMarshalTo = ContentType(`application/json`) :: Nil
def marshal(value: A, contentType: ContentType) = {
val jsonSource = write(value)
DefaultMarshallers.StringMarshaller.marshal(jsonSource, contentType)
}
}
}
trait Unmarshallers extends DefaultUnmarshallers {
this: LiftJSON =>
implicit def liftJsonUnmarshaller[A <: Product : Manifest] = new SimpleUnmarshaller[A] {
val canUnmarshalFrom = ContentTypeRange(`application/json`) :: Nil
def unmarshal(content: HttpContent) = protect {
val jsonSource = DefaultUnmarshallers.StringUnmarshaller(content).right.get
parse(jsonSource).extract[A]
}
}
}
trait LiftJSON {
implicit def liftJsonFormats: Formats =
DefaultFormats + new UUIDSerializer + FieldSerializer[AnyRef]()
class UUIDSerializer extends Serializer[UUID] {
private val UUIDClass = classOf[UUID]
def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), UUID] = {
case (TypeInfo(UUIDClass, _), json) => json match {
case JString(s) => UUID.fromString(s)
case x => throw new MappingException("Can't convert " + x + " to UUID")
}
}
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case x: UUID => JString(x.toString)
}
}
class StringBuilderMarshallingContent(sb: StringBuilder) extends MarshallingContext {
def marshalTo(content: HttpContent) {
if (sb.length > 0) sb.append(",")
sb.append(new String(content.buffer))
}
def handleError(error: Throwable) {}
def startChunkedMessage(contentType: ContentType) = throw new UnsupportedOperationException
}
}