-
Notifications
You must be signed in to change notification settings - Fork 22
/
JsonSection.scala
144 lines (132 loc) · 4.53 KB
/
JsonSection.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* scala-exercises - exercises-circe
* Copyright (C) 2015-2016 47 Degrees, LLC. <http://www.47deg.com>
*/
package circelib
import io.circe.Json
import org.scalaexercises.definitions
import org.scalatest._
import circelib.helpers.JsonHelpers
/** @param name Json
*/
object JsonSection extends FlatSpec with Matchers with definitions.Section {
import JsonHelpers._
/** Json is the circe data type representing a Json object. It's very useful to be familiar with this data type since
* it's how circe models the base type we want to address.
*
* To begin, let's briefly talk about the shape of every Json object. It's basically semi-structured data built on
* top of key-value pairs. These key-value pairs have a specific shape:
* - keys are strings.
* - values can be multiple types.
*
* Next, to model a real json object, we need to support different data types in the value field. For this purpose,
* we have different available methods so we can create a Json object from different source data types. Some examples
* of these methods are `fromString`, `fromBoolean`, `fromDouble` and so on. For further details about all possible
* methods, see the [[http://circe.github.io/circe/api/io/circe/Json$.html Scala docs]].
*
* Let's take a look at how these methods work.
*
* {{{
* scala> import io.circe.Json
* scala> // fromString example
* scala> val jsonString: Json = Json.fromString("scala exercises")
* jsonString: io.circe.Json = "scala exercises"
*
* scala> // fromDouble example
* scala> val jsonDouble: Option[Json] = Json.fromDouble(1)
* jsonDouble: Option[io.circe.Json] = Some(1.0)
*
* scala> val jsonDouble: Option[Json] = Json.fromDouble(1)
* jsonString: Option[io.circe.Json] = Some(1.0)
*
* scala> // fromFields example
* scala> val fieldList = List(
* ("key1", Json.fromString("value1")),
* ("key2", Json.fromInt(1)))
* fieldList: List[(String, io.circe.Json)] = List((key1,"value1"), (key2,1))
*
* scala> val jsonFromFields: Json = Json.fromFields(fieldList)
* jsonFromFields: io.circe.Json =
* {
* "key1" : "value1",
* "key2" : 1
* }
*
* }}}
*
*
* In addition, there are a few other methods that allow you to convert a Json object to a String.
*
* {{{
*
* scala> jsonFromFields.noSpaces
* res0: String = {"name":"sample json","version":1,"data":{"done":false,"rate":4.9}}
*
* scala> jsonFromFields.spaces2
* res1: String =
* {
* "name" : "sample json",
* "version" : 1,
* "data" : {
* "done" : false,
* "rate" : 4.9
* }
* }
*
* scala> jsonFromFields.spaces4
* res2: String =
* {
* "name" : "sample json",
* "version" : 1,
* "data" : {
* "done" : false,
* "rate" : 4.9
* }
* }
*
* }}}
*
* What would be the string output for our jsonFromFields value?
*/
def jsonToString(res0: String) =
jsonFromFields.noSpaces should be(res0)
/** Let's see how we can use these methods to create custom Jsons that represents specific Json strings.
*/
def jsonObject(res0: Json, res1: (String, Json), res2: (String, Json), res3: Json) = {
"{\"key\":\"value\"}" should be(res0.noSpaces)
"{\"name\":\"sample json\",\"data\":{\"done\":false}}" should be(
Json.fromFields(List(res1, res2)).noSpaces)
"[{\"x\":1}]" should be(res3.noSpaces)
}
/** Furthemore, there are some other methods that allow you to deal with Json objects and apply transformation. We
* can use them to modify or apply any changes to a given Json object in a simpler way, as if we we're dealing with it
* manually.
*
* We are going to start with this Json array:
*
* {{{
* val jsonArray: Json = Json.fromValues(List(
* Json.fromFields(List(("field1", Json.fromInt(1)))),
* Json.fromFields(List(
* ("field1", Json.fromInt(200)),
* ("field2", Json.fromString("Having circe in Scala Exercises is awesome"))
* ))
* ))
*
* }}}
*
* Finally, we have a transformJson method:
*
* {{{
* def transformJson(jsonArray: Json): Json =
* jsonArray mapArray { oneJson: List[Json] =>
* oneJson.init
* }
* }}}
*
* So, with these in mind, what should be the result if we apply our transformJson function to our jsonArray value?
*
*/
def jsonClass(res0: String) =
transformJson(jsonArray).noSpaces should be(res0)
}