1
|
|
package hammock
|
2
|
|
|
3
|
|
import cats._
|
4
|
|
import monocle._
|
5
|
|
|
6
|
|
sealed trait Entity {
|
7
|
|
type Content
|
8
|
|
|
9
|
|
def contentType: ContentType
|
10
|
|
def content: Content
|
11
|
|
def contentLength: Long
|
12
|
|
def chunked: Boolean
|
13
|
|
def repeatable: Boolean
|
14
|
|
def streaming: Boolean
|
15
|
|
|
16
|
|
def cata[X](
|
17
|
|
onStringEntity: Entity.StringEntity => X,
|
18
|
|
onByteArrayEntity: Entity.ByteArrayEntity => X,
|
19
|
|
onEmptyEntity: Entity.EmptyEntity.type => X
|
20
|
|
): X = this match {
|
21
|
1
|
case e: Entity.StringEntity => onStringEntity(e)
|
22
|
1
|
case e: Entity.ByteArrayEntity => onByteArrayEntity(e)
|
23
|
0
|
case Entity.EmptyEntity => onEmptyEntity(Entity.EmptyEntity)
|
24
|
|
}
|
25
|
|
}
|
26
|
|
|
27
|
|
object Entity {
|
28
|
|
case object EmptyEntity extends Entity {
|
29
|
|
type Content = Unit
|
30
|
0
|
def content = ()
|
31
|
1
|
def contentType = ContentType.notUsed
|
32
|
1
|
def contentLength = 0
|
33
|
1
|
def chunked = false
|
34
|
1
|
def repeatable = true
|
35
|
1
|
def streaming = false
|
36
|
|
}
|
37
|
|
|
38
|
|
case class StringEntity(body: String, contentType: ContentType = ContentType.`text/plain`) extends Entity {
|
39
|
|
type Content = String
|
40
|
1
|
def content = body
|
41
|
1
|
def contentLength = body.size.toLong
|
42
|
0
|
def chunked = false
|
43
|
0
|
def repeatable = true
|
44
|
0
|
def streaming = false
|
45
|
|
}
|
46
|
|
|
47
|
|
case class ByteArrayEntity(body: Array[Byte], contentType: ContentType = ContentType.`application/octet-stream`) extends Entity {
|
48
|
|
type Content = Array[Byte]
|
49
|
0
|
def chunked: Boolean = false
|
50
|
1
|
def content: Array[Byte] = body
|
51
|
1
|
def contentLength: Long = body.length.toLong
|
52
|
0
|
def repeatable: Boolean = true
|
53
|
0
|
def streaming: Boolean = false
|
54
|
|
}
|
55
|
|
|
56
|
0
|
implicit val eq: Eq[Entity] = Eq.fromUniversalEquals
|
57
|
|
|
58
|
|
val string: Prism[Entity, String] =
|
59
|
0
|
Prism.partial[Entity, String]{case StringEntity(body, _) => body}(StringEntity(_, ContentType.`text/plain`))
|
60
|
|
|
61
|
|
val byteArray: Prism[Entity, Array[Byte]] =
|
62
|
0
|
Prism.partial[Entity, Array[Byte]]{case ByteArrayEntity(body, _) => body}(ByteArrayEntity(_, ContentType.`application/octet-stream`))
|
63
|
|
}
|