Skip to content

Commit 1d5309b

Browse files
ataisplokhotnyuk
authored andcommitted
added some real life example scenarios (#330)
1 parent e635f40 commit 1d5309b

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.github.plokhotnyuk.jsoniter_scala.examples
2+
3+
import com.github.plokhotnyuk.jsoniter_scala.core._
4+
import com.github.plokhotnyuk.jsoniter_scala.macros.{CodecMakerConfig, JsonCodecMaker}
5+
6+
import scala.annotation.switch
7+
8+
/**
9+
* When json structure becomes tricky, you can actually use different codecs,
10+
* even in the codecs itself.
11+
*/
12+
object EncodedExample {
13+
14+
case class RequestData(id: String, load: Int, important: Boolean)
15+
16+
case class Request(url: String, data: RequestData)
17+
18+
implicit lazy val requestCodec: JsonValueCodec[Request] = JsonCodecMaker.make[Request](CodecMakerConfig()) // LAZY is important
19+
20+
lazy private val requestDataDirectCodec: JsonValueCodec[RequestData] = JsonCodecMaker.make[RequestData](CodecMakerConfig()) // not implicit!
21+
lazy private val requestDataEncodedCodec: JsonValueCodec[RequestData] = new JsonValueCodec[RequestData] { // not implicit!
22+
override def decodeValue(in: JsonReader, default: RequestData): RequestData = {
23+
val json = in.readString("")
24+
readFromString(json)(requestDataDirectCodec)
25+
}
26+
27+
override def encodeValue(x: RequestData, out: JsonWriter): Unit = requestDataDirectCodec.encodeValue(x, out)
28+
29+
override def nullValue: RequestData = requestDataDirectCodec.nullValue
30+
}
31+
32+
implicit lazy private val requestDataCodec: JsonValueCodec[RequestData] = new JsonValueCodec[RequestData] { // implicit
33+
34+
@scala.annotation.tailrec
35+
override def decodeValue(in: JsonReader, default: RequestData): RequestData = {
36+
(in.nextToken(): @switch) match {
37+
case ' ' =>
38+
this.decodeValue(in, default)
39+
case '{' =>
40+
in.rollbackToken()
41+
requestDataDirectCodec.decodeValue(in, default)
42+
case '"' =>
43+
in.rollbackToken()
44+
requestDataEncodedCodec.decodeValue(in, default)
45+
case _ =>
46+
in.decodeError("""expected '{' or '"' in request>data field""")
47+
}
48+
}
49+
50+
override def encodeValue(x: RequestData, out: JsonWriter): Unit = requestDataDirectCodec.encodeValue(x, out)
51+
52+
override def nullValue: RequestData = requestDataDirectCodec.nullValue
53+
}
54+
55+
56+
def main(args: Array[String]): Unit = {
57+
val normalJson =
58+
"""{
59+
| "url": "http://google.com",
60+
| "data": {
61+
| "id": "abcdefghijklmn",
62+
| "load": 10,
63+
| "important": true
64+
| }
65+
|}
66+
""".stripMargin
67+
68+
val normal: Request = readFromString(normalJson)(requestCodec) // same codec!
69+
println(normal)
70+
println(writeToString(normal))
71+
72+
val escapedJson =
73+
"""{
74+
| "url": "http://google.com",
75+
| "data": "{\"id\":\"abcdefghijklmn\",\"load\":10,\"important\":true}"
76+
|}
77+
""".stripMargin
78+
val escaped: Request = readFromString(escapedJson)(requestCodec) // same codec!
79+
println(escaped)
80+
println(writeToString(escaped))
81+
}
82+
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.github.plokhotnyuk.jsoniter_scala.examples
2+
3+
import com.github.plokhotnyuk.jsoniter_scala.core.{JsonReader, JsonValueCodec, JsonWriter, _}
4+
import com.github.plokhotnyuk.jsoniter_scala.macros.{CodecMakerConfig, JsonCodecMaker}
5+
6+
/**
7+
* Example showing how to handle enums or
8+
* any data that has different representation in json than in your model.
9+
*/
10+
object EnumExample {
11+
12+
sealed abstract class HttpProtocol private(val value: Int)
13+
14+
case object HttpProtocol {
15+
val values = Seq(Http, Https) // I normally use Enumeratum
16+
17+
case object Http extends HttpProtocol(0)
18+
19+
case object Https extends HttpProtocol(1)
20+
21+
}
22+
23+
case class Request(url: String, protocol: HttpProtocol)
24+
25+
26+
implicit lazy val requestCodec: JsonValueCodec[Request] = JsonCodecMaker.make[Request](CodecMakerConfig()) // LAZY is important
27+
28+
implicit lazy val protocolCodec: JsonValueCodec[HttpProtocol] = new JsonValueCodec[HttpProtocol] {
29+
override def decodeValue(in: JsonReader, default: HttpProtocol): HttpProtocol = {
30+
val i = in.readInt()
31+
HttpProtocol.values.find(_.value == i).getOrElse(nullValue) // exception handling?
32+
}
33+
34+
override def encodeValue(x: HttpProtocol, out: JsonWriter): Unit = out.writeVal(x.value)
35+
36+
override def nullValue: HttpProtocol = ??? // this should never be used
37+
}
38+
39+
40+
def main(args: Array[String]): Unit = {
41+
val jsonHttp =
42+
"""{
43+
| "url": "http://google.com",
44+
| "protocol": 0
45+
|}
46+
|""".stripMargin
47+
48+
val http: Request = readFromString(jsonHttp)(requestCodec)
49+
println(http)
50+
println(writeToString(http))
51+
52+
53+
val jsonHttps =
54+
"""{
55+
| "url": "http://google.com",
56+
| "protocol": 1
57+
|}
58+
|""".stripMargin
59+
60+
val https: Request = readFromString(jsonHttps)(requestCodec)
61+
println(https)
62+
println(writeToString(https))
63+
}
64+
65+
}

0 commit comments

Comments
 (0)