Skip to content

Commit f7fc5b0

Browse files
committed
docs: use tabs
1 parent bfbff18 commit f7fc5b0

File tree

1 file changed

+122
-53
lines changed

1 file changed

+122
-53
lines changed

docs/index.md renamed to docs/index.mdx

+122-53
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ title: "Getting Started with ZIO Json"
44
sidebar_label: "Getting Started"
55
---
66

7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
710
[ZIO Json](https://github.com/zio/zio-json) is a fast and secure JSON library with tight ZIO integration.
811

912
@PROJECT_BADGES@
@@ -34,10 +37,23 @@ Let's try a simple example of encoding and decoding JSON using ZIO JSON.
3437

3538
All the following code snippets assume that the following imports have been declared
3639

40+
<Tabs groupId="language">
41+
<TabItem value="scala 2" label="Scala 2">
42+
3743
```scala
3844
import zio.json._
3945
```
4046

47+
</TabItem>
48+
<TabItem value="scala 3" label="Scala 3" default>
49+
50+
```scala
51+
import zio.json.*
52+
```
53+
54+
</TabItem>
55+
</Tabs>
56+
4157
Say we want to be able to read some JSON like
4258

4359
```json
@@ -50,21 +66,30 @@ into a Scala `case class`
5066
case class Banana(curvature: Double)
5167
```
5268

69+
<Tabs groupId="language">
70+
<TabItem value="scala 2" label="Scala 2">
71+
72+
To do this, we create an *instance* of the `JsonDecoder` typeclass for `Banana` using the `zio-json` code generator. It is best practice to put it on the companion of `Banana`, like so
73+
74+
```scala
75+
object Banana {
76+
implicit val decoder: JsonDecoder[Banana] = DeriveJsonDecoder.gen[Banana]
77+
}
78+
```
79+
80+
</TabItem>
81+
<TabItem value="scala 3" label="Scala 3" default>
82+
5383
To do this, we derive an *instance* of the `JsonDecoder` typeclass for `Banana`.
5484

5585
```scala
5686
case class Banana(curvature: Double) derives JsonDecoder
5787
```
5888

59-
> [!NOTE]
60-
>
61-
> In scala 2, we need to use the `zio-json` code generator. It is best practice to put it on the companion of `Banana`, like so
62-
>
63-
> ```scala
64-
> object Banana {
65-
> implicit val decoder: JsonDecoder[Banana] = DeriveJsonDecoder.gen[Banana]
66-
> }
67-
> ```
89+
Note: If your case class is defining default parameters, -Yretain-trees needs to be added to scalacOptions.
90+
91+
</TabItem>
92+
</Tabs>
6893

6994
Now we can parse JSON into our object
7095

@@ -75,9 +100,27 @@ val res: Either[String, Banana] = Right(Banana(0.5))
75100

76101
Likewise, to produce JSON from our data we derive a `JsonEncoder`
77102

103+
<Tabs groupId="language">
104+
<TabItem value="scala 2" label="Scala 2">
105+
106+
```scala
107+
object Banana {
108+
...
109+
implicit val encoder: JsonEncoder[Banana] = DeriveJsonEncoder.gen[Banana]
110+
}
111+
```
112+
113+
</TabItem>
114+
<TabItem value="scala 3" label="Scala 3" default>
115+
78116
```scala
79117
case class Banana(curvature: Double) derives JsonEncoder
118+
```
119+
120+
</TabItem>
121+
</Tabs>
80122

123+
```
81124
scala> Banana(0.5).toJson
82125
val res: String = {"curvature":0.5}
83126
@@ -88,16 +131,6 @@ val res: String =
88131
}
89132
```
90133

91-
> [!NOTE]
92-
>
93-
> In scala 2:
94-
> ```scala
95-
> object Banana {
96-
> ...
97-
> implicit val encoder: JsonEncoder[Banana] = DeriveJsonEncoder.gen[Banana]
98-
> }
99-
> ```
100-
101134
And bad JSON will produce an error in `jq` syntax with an additional piece of contextual information (in parentheses)
102135

103136
```
@@ -107,49 +140,50 @@ val res: Either[String, Banana] = Left(.curvature(expected a number, got w))
107140

108141
Say we extend our data model to include more data types
109142

143+
<Tabs groupId="language">
144+
<TabItem value="scala 2" label="Scala 2">
145+
146+
```scala
147+
sealed trait Fruit
148+
case class Banana(curvature: Double) extends Fruit
149+
case class Apple (poison: Boolean) extends Fruit
150+
```
151+
152+
</TabItem>
153+
<TabItem value="scala 3" label="Scala 3" default>
154+
110155
```scala
111156
enum Fruit:
112157
case Banana(curvature: Double) extends Fruit
113-
case Apple(poison: Boolean) extends Fruit
158+
case Apple (poison: Boolean) extends Fruit
159+
```
160+
161+
</TabItem>
162+
</Tabs>
163+
164+
we can generate the encoder and decoder for the entire `sealed` family
165+
166+
<Tabs groupId="language">
167+
<TabItem value="scala 2" label="Scala 2">
168+
169+
```scala
170+
object Fruit {
171+
implicit val decoder: JsonDecoder[Fruit] = DeriveJsonDecoder.gen[Fruit]
172+
implicit val encoder: JsonEncoder[Fruit] = DeriveJsonEncoder.gen[Fruit]
173+
}
114174
```
115175

116-
we can generate the encoder and decoder for the entire `sealed` family using `JsonCodec`
176+
</TabItem>
177+
<TabItem value="scala 3" label="Scala 3" default>
117178

118179
```scala
119180
enum Fruit derives JsonCodec:
120181
case Banana(curvature: Double)
121-
case Apple(poison: Boolean)
122-
```
123-
124-
> [!NOTE]
125-
>
126-
> In scala 2:
127-
>
128-
> ```scala mdoc:compile-only
129-
> import zio.json._
130-
>
131-
> sealed trait Fruit extends Product with Serializable
132-
> case class Banana(curvature: Double) extends Fruit
133-
> case class Apple(poison: Boolean) extends Fruit
134-
>
135-
> object Fruit {
136-
> implicit val decoder: JsonDecoder[Fruit] =
137-
> DeriveJsonDecoder.gen[Fruit]
138-
>
139-
> implicit val encoder: JsonEncoder[Fruit] =
140-
> DeriveJsonEncoder.gen[Fruit]
141-
> }
142-
>
143-
> val json1 = """{ "Banana":{ "curvature":0.5 }}"""
144-
> val json2 = """{ "Apple": { "poison": false }}"""
145-
> val malformedJson = """{ "Banana":{ "curvature": true }}"""
146-
>
147-
> json1.fromJson[Fruit]
148-
> json2.fromJson[Fruit]
149-
> malformedJson.fromJson[Fruit]
150-
>
151-
> List(Apple(false), Banana(0.4)).toJsonPretty
152-
> ```
182+
case Apple (poison: Boolean)
183+
```
184+
185+
</TabItem>
186+
</Tabs>
153187

154188
allowing us to load the fruit based on a single field type tag in the JSON
155189

@@ -163,6 +197,38 @@ val res: Either[String, Fruit] = Right(Apple(false))
163197

164198
Almost all of the standard library data types are supported as fields on the case class, and it is easy to add support if one is missing.
165199

200+
<Tabs groupId="language">
201+
<TabItem value="scala 2" label="Scala 2">
202+
203+
```scala mdoc:compile-only
204+
import zio.json._
205+
206+
sealed trait Fruit extends Product with Serializable
207+
case class Banana(curvature: Double) extends Fruit
208+
case class Apple(poison: Boolean) extends Fruit
209+
210+
object Fruit {
211+
implicit val decoder: JsonDecoder[Fruit] =
212+
DeriveJsonDecoder.gen[Fruit]
213+
214+
implicit val encoder: JsonEncoder[Fruit] =
215+
DeriveJsonEncoder.gen[Fruit]
216+
}
217+
218+
val json1 = """{ "Banana":{ "curvature":0.5 }}"""
219+
val json2 = """{ "Apple": { "poison": false }}"""
220+
val malformedJson = """{ "Banana":{ "curvature": true }}"""
221+
222+
json1.fromJson[Fruit]
223+
json2.fromJson[Fruit]
224+
malformedJson.fromJson[Fruit]
225+
226+
List(Apple(false), Banana(0.4)).toJsonPretty
227+
```
228+
229+
</TabItem>
230+
<TabItem value="scala 3" label="Scala 3" default>
231+
166232
```scala
167233
import zio.json.*
168234

@@ -183,6 +249,9 @@ malformedJson.fromJson[Fruit]
183249
List(Apple(false), Banana(0.4)).toJsonPretty
184250
```
185251

252+
</TabItem>
253+
</Tabs>
254+
186255
# How
187256

188257
Extreme **performance** is achieved by decoding JSON directly from the input source into business objects (inspired by [plokhotnyuk](https://github.com/plokhotnyuk/jsoniter-scala)). Although not a requirement, the latest advances in [Java Loom](https://wiki.openjdk.java.net/display/loom/Main) can be used to support arbitrarily large payloads with near-zero overhead.

0 commit comments

Comments
 (0)