Skip to content

Commit

Permalink
Updating Decoding doc with example of writing custom decoder (#1089)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremycod authored Apr 15, 2024
1 parent b9cab26 commit e1f34bd
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions docs/decoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,47 @@ implicit val decodeName: JsonDecoder[String Refined NonEmpty] =
```

Now the code compiles.

### Writing a Custom Decoder
In some rare cases, you might encounter situations where the data format deviates from the expected structure.

#### Problem
Let's consider an Animal case class with a categories field that should be a list of strings. However, some JSON data might represent the categories as a comma-separated string instead of a proper list.

```scala mdoc
import zio.json.ast.Json
case class Animal(name: String, categories: List[String])
```


#### The Solution: Custom Decoder

We can create custom decoders to handle specific data formats. Here's an implementation for our Animal case class:
```scala mdoc
object Animal {
implicit val decoder: JsonDecoder[Animal] = JsonDecoder[Json].mapOrFail {
case Json.Obj(fields) =>
(for {
name <- fields.find(_._1 == "name").map(_._2.toString())
categories <- fields
.find(_._1 == "categories").map(_._2.toString())
} yield Right(Animal(name, handleCategories(categories))))
.getOrElse(Left("DecodingError"))
case _ => Left("Error")
}

private def handleCategories(categories: String): List[String] = {
val decodedList = JsonDecoder[List[String]].decodeJson(categories)
decodedList match {
case Right(list) => list
case Left(_) =>
categories.replaceAll("\"", "").split(",").toList
}
}
}
```
And now, JsonDecoder for Animal can handle both formats:
``` scala mdoc
"""{"name": "Dog", "categories": "Warm-blooded, Mammal"}""".fromJson[Animal]
"""{"name": "Snake", "categories": [ "Cold-blooded", "Reptile"]}""".fromJson[Animal]
```

0 comments on commit e1f34bd

Please sign in to comment.