Skip to content
Permalink
Browse files

Attempt to fix microsite

  • Loading branch information
travisbrown committed Dec 18, 2019
1 parent 4b11ac4 commit 705e2c047dd57465930c043d21f0da48dc06307c
@@ -19,7 +19,7 @@ install:
- rvm use 2.6.5 --install --fuzzy
- yes | gem update --system --force
- gem install sass
- gem install jekyll -v 3.8.5
- gem install jekyll -v 4.0.0

script:
- sbt ++$TRAVIS_SCALA_VERSION clean coverage validateJVM benchmark/test;
@@ -122,8 +122,8 @@ lazy val docSettings = allSettings ++ Seq(
micrositeAuthor := "Travis Brown",
micrositeHighlightTheme := "atom-one-light",
micrositeHomepage := "https://circe.github.io/circe/",
micrositeBaseUrl := "circe",
micrositeDocumentationUrl := "api",
micrositeBaseUrl := "/circe",
micrositeDocumentationUrl := "/api",
micrositeGithubOwner := "circe",
micrositeGithubRepo := "circe",
micrositeExtraMdFiles := Map(file("CONTRIBUTING.md") -> ExtraMdFileConfig("contributing.md", "docs")),
@@ -169,7 +169,7 @@ lazy val docs = project
.settings(
moduleName := "circe-docs",
name := "Circe docs",
crossScalaVersions := crossScalaVersions.value.filterNot(_.startsWith("2.13")),
mdocIn := file("docs/src/main/tut"),
libraryDependencies ++= Seq(
"io.circe" %% "circe-generic-extras" % "0.12.2",
"io.circe" %% "circe-optics" % "0.12.0"
@@ -15,22 +15,22 @@ provides instances for `List[A]`, `Option[A]`, and other generic types, but only

Encoding data to `Json` can be done using the `.asJson` syntax:

```tut:book
```scala mdoc
import io.circe.syntax._
val intsJson = List(1, 2, 3).asJson
```

Use the `.as` syntax for decoding data from `Json`:

```tut:book
```scala mdoc
intsJson.as[List[Int]]
```

The `decode` function from the included [parser] module can be used to directly decode
a JSON `String`:

```tut:book
```scala mdoc
import io.circe.parser.decode
decode[List[Int]]("[1, 2, 3]")
@@ -9,7 +9,7 @@ The most straightforward way to encode / decode ADTs is by using generic derivat

Consider the following ADT:

```tut:book:silent
```scala mdoc:silent
sealed trait Event
case class Foo(i: Int) extends Event
@@ -20,7 +20,7 @@ case class Qux(values: List[String]) extends Event

And the encoder / decoder instances:

```tut:book:silent
```scala mdoc:silent
import cats.syntax.functor._
import io.circe.{ Decoder, Encoder }, io.circe.generic.auto._
import io.circe.syntax._
@@ -49,7 +49,7 @@ It's also worth noting that our explicit `Encoder` and `Decoder` instances will

We can use these instances like this:

```tut:book
```scala mdoc
import GenericDerivation._
import io.circe.parser.decode
@@ -64,7 +64,7 @@ This works, and if you need to be able to specify the order that the ADT constru

As discussed [on Gitter](https://gitter.im/circe/circe?at=589dee5daa800ee52c7aac8a), we can avoid the fuss of writing out all the cases by using the `circe-shapes` module:

```tut:book:silent
```scala mdoc:silent
// To suppress previously imported inplicit codecs.
import GenericDerivation.{ decodeEvent => _, encodeEvent => _ }
@@ -87,7 +87,7 @@ object ShapesDerivation {

And then:

```tut:book
```scala mdoc
import ShapesDerivation._
import io.circe.parser.decode, io.circe.syntax._
@@ -104,7 +104,7 @@ The main drawback of this approach (apart from the extra `circe-shapes` dependen

The `generic-extras` module provides a little more configurability in this respect. We can write the following, for example:

```tut:book:silent
```scala mdoc:silent
import io.circe.generic.extras.auto._
import io.circe.generic.extras.Configuration
@@ -114,7 +114,7 @@ implicit val genDevConfig: Configuration =

And then:

```tut:book
```scala mdoc
import io.circe.parser.decode, io.circe.syntax._
(Foo(100): Event).asJson.noSpaces
@@ -7,7 +7,7 @@ title: "Automatic derivation"

It is also possible to derive `Encoder`s and `Decoder`s for many types with no boilerplate at all. Circe uses [shapeless](https://github.com/milessabin/shapeless) to automatically derive the necessary type class instances:

```tut:book
```scala mdoc
import io.circe.generic.auto._, io.circe.syntax._
case class Person(name: String)
@@ -9,7 +9,7 @@ If you want to write your own codec instead of using automatic or semi-automatic

Firstly, you can write a new `Encoder[A]` and `Decoder[A]` from scratch:

```tut:book
```scala mdoc
import io.circe.{ Decoder, Encoder, HCursor, Json }
class Thing(val foo: String, val bar: Int)
@@ -35,15 +35,15 @@ implicit val decodeFoo: Decoder[Thing] = new Decoder[Thing] {
But in many cases you might find it more convenient to piggyback on top of the decoders that are
already available. For example, a codec for `java.time.Instant` might look like this:

```tut:book
import cats.syntax.either._
```scala mdoc
import io.circe.{ Decoder, Encoder }
import java.time.Instant
import scala.util.Try
implicit val encodeInstant: Encoder[Instant] = Encoder.encodeString.contramap[Instant](_.toString)
implicit val decodeInstant: Decoder[Instant] = Decoder.decodeString.emap { str =>
Either.catchNonFatal(Instant.parse(str)).leftMap(t => "Instant")
implicit val decodeInstant: Decoder[Instant] = Decoder.decodeString.emapTry { str =>
Try(Instant.parse(str))
}
```

@@ -61,7 +61,7 @@ you need to provide a `KeyEncoder` and/or `KeyDecoder` for your custom key type.

For example:

```tut:book
```scala mdoc
import io.circe._, io.circe.syntax._
case class Foo(value: String)
@@ -93,7 +93,7 @@ names during encoding and decoding.
In many cases the transformation is as simple as going from camel case to snake case, in which case
all you need is a custom implicit configuration:

```tut:book
```scala mdoc
import io.circe.generic.extras._, io.circe.syntax._
implicit val config: Configuration = Configuration.default.withSnakeCaseMemberNames
@@ -105,7 +105,7 @@ User("Foo", "McBar").asJson

In other cases you may need more complex mappings. These can be provided as a function:

```tut:book
```scala mdoc:reset
import io.circe.generic.extras._, io.circe.syntax._
implicit val config: Configuration = Configuration.default.copy(
@@ -122,7 +122,7 @@ Bar(13, "Qux").asJson

Since this is a common use case, we also support for mapping member names via an annotation:

```tut:book
```scala mdoc:reset
import io.circe.generic.extras._, io.circe.syntax._
implicit val config: Configuration = Configuration.default
@@ -135,7 +135,7 @@ Bar(13, "Qux").asJson
It's worth noting that if you don't want to use the experimental generic-extras module, the
completely unmagical `forProductN` version isn't really that much of a burden:

```tut:book
```scala mdoc:reset
import io.circe.Encoder, io.circe.syntax._
case class User(firstName: String, lastName: String)
@@ -7,7 +7,7 @@ title: "Semi-automatic derivation"

Sometimes it's convenient to have an `Encoder` or `Decoder` defined in your code, and semi-automatic derivation can help. You'd write:

```tut:silent
```scala mdoc:silent
import io.circe._, io.circe.generic.semiauto._
case class Foo(a: Int, b: String, c: Boolean)
@@ -18,7 +18,11 @@ implicit val fooEncoder: Encoder[Foo] = deriveEncoder[Foo]

Or simply:

```tut:silent
```scala mdoc:silent:reset
import io.circe._, io.circe.generic.semiauto._
case class Foo(a: Int, b: String, c: Boolean)
implicit val fooDecoder: Decoder[Foo] = deriveDecoder
implicit val fooEncoder: Encoder[Foo] = deriveEncoder
```
@@ -28,7 +32,7 @@ implicit val fooEncoder: Encoder[Foo] = deriveEncoder
The circe-generic project includes a `@JsonCodec` annotation that simplifies the
use of semi-automatic generic derivation:

```tut:book
```scala mdoc
import io.circe.generic.JsonCodec, io.circe.syntax._
@JsonCodec case class Bar(i: Int, s: String)
@@ -45,7 +49,7 @@ NOTE: You will need the [Macro Paradise](https://docs.scala-lang.org/overviews/m
It's also possible to construct encoders and decoders for case class-like types
in a relatively boilerplate-free way without generic derivation:

```tut:book
```scala mdoc
import io.circe.{ Decoder, Encoder }
case class User(id: Long, firstName: String, lastName: String)
@@ -11,7 +11,7 @@ data and for performing modification.

Suppose we have the following JSON document:

```tut:silent
```scala mdoc:silent
import cats.syntax.either._
import io.circe._, io.circe.parser._
@@ -36,14 +36,14 @@ val doc: Json = parse(json).getOrElse(Json.Null)
In order to traverse the document we need to create an `HCursor` with the focus at the document's
root:

```tut:silent
```scala mdoc:silent
val cursor: HCursor = doc.hcursor
```

We can then use [various operations][circe-cursor] to move the focus of the cursor around the
document and extract data from it:

```tut:book
```scala mdoc
val baz: Decoder.Result[Double] =
cursor.downField("values").downField("baz").as[Double]
@@ -59,14 +59,14 @@ val secondQux: Decoder.Result[String] =

We can also use a cursor to modify JSON.

```tut:silent
```scala mdoc:silent
val reversedNameCursor: ACursor =
cursor.downField("name").withFocus(_.mapString(_.reverse))
```

We can then return to the root of the document and return its value with `top`:

```tut:book
```scala mdoc
val reversedName: Option[Json] = reversedNameCursor.top
```

@@ -22,8 +22,7 @@ Note that this will require your project to depend on both Scalaz and cats.

Suppose we have the following JSON document:

```tut:silent
import cats.syntax.either._
```scala mdoc:silent
import io.circe._, io.circe.parser._
val json: Json = parse("""
@@ -53,8 +52,8 @@ val json: Json = parse("""

If we wanted to get the customer's phone number, we could do it using a cursor as follows:

```tut:book
val phoneNum: Option[String] = json.hcursor.
```scala mdoc
val phoneNumFromCursor: Option[String] = json.hcursor.
downField("order").
downField("customer").
downField("contactDetails").
@@ -64,7 +63,7 @@ val phoneNum: Option[String] = json.hcursor.

This works, but it's a little verbose. We could rewrite it using optics like this:

```tut:book
```scala mdoc
import io.circe.optics.JsonPath._
val _phoneNum = root.order.customer.contactDetails.phone.string
@@ -83,21 +82,21 @@ traversals together, and so on.
Let's look at a more complex example. This time we want to get the quantities of all the
items in the order. Using a cursor it might look like this:

```tut:book
val items: Vector[Json] = json.hcursor.
```scala mdoc
val itemsFromCursor: Vector[Json] = json.hcursor.
downField("order").
downField("items").
focus.
flatMap(_.asArray).
getOrElse(Vector.empty)
val quantities: Vector[Int] =
items.flatMap(_.hcursor.get[Int]("quantity").toOption)
itemsFromCursor.flatMap(_.hcursor.get[Int]("quantity").toOption)
```

And with optics:

```tut:book
```scala mdoc
val items: List[Int] =
root.order.items.each.quantity.int.getAll(json)
```
@@ -109,7 +108,7 @@ Optics can also be used for making modifications to JSON.
Suppose we decide to have a 2-for-1 sale, so we want to double all the quantities in the order. This
can be achieved with a small change to the code we wrote for traversal:

```tut:book
```scala mdoc
val doubleQuantities: Json => Json =
root.order.items.each.quantity.int.modify(_ * 2)
@@ -123,7 +122,7 @@ The result is a copy of the original JSON with only the `quantity` fields update
Sometimes you may need to recursively modify JSON. Let assume you need to transform all numbers into
strings in the example JSON:

```tut:book
```scala mdoc
import io.circe.optics.JsonOptics._
import monocle.function.Plated
@@ -16,7 +16,7 @@ libraryDependencies += "io.circe" %% "circe-parser" % circeVersion

Parsing is done as follows.

```tut:book
```scala mdoc
import io.circe._, io.circe.parser._
val rawJson: String = """
@@ -36,7 +36,7 @@ corresponding JSON representation.

Let's see what happens when you try to parse invalid JSON:

```tut:book
```scala mdoc
val badJson: String = "yolo"
parse(badJson)
@@ -45,7 +45,7 @@ parse(badJson)
There are a number of ways to extract the parse result from the `Either`. For example you could pattern
match on it:

```tut:book
```scala mdoc
parse(rawJson) match {
case Left(failure) => println("Invalid JSON :(")
case Right(json) => println("Yay, got some JSON!")
@@ -54,9 +54,7 @@ parse(rawJson) match {

Or use `getOrElse` (an extension method provided by Cats):

```tut:book
import cats.syntax.either._
```scala mdoc
val json: Json = parse(rawJson).getOrElse(Json.Null)
```

0 comments on commit 705e2c0

Please sign in to comment.
You can’t perform that action at this time.