Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial sketch of optics module #78

Merged
merged 5 commits into from
Nov 25, 2015
Merged

Initial sketch of optics module #78

merged 5 commits into from
Nov 25, 2015

Conversation

travisbrown
Copy link
Member

This is a partial port from Argonaut in response to #39 and this question. If we can get some docs and tests in place before Shapeless 2.3.0 is out, I'd be happy to publish this with 0.2.0, but I don't want to wait for it.

@codecov-io
Copy link

Current coverage is 75.10%

Merging #78 into master will increase coverage by +1.93% as of 7df3639

Powered by Codecov. Updated on successful CI builds.

@travisbrown
Copy link
Member Author

Example usage:

import cats.data.Xor
import io.circe._, generic.auto._, jawn._, optics._
import monocle.macros.Lenses

@Lenses case class Foo(count: Int)
@Lenses case class Qux(foo: Foo, s: String)

val toQux = JsonPath.root.x.y.at(2).as[Qux]
val incrementCount = toQux.composeLens(Qux.foo).composeLens(Foo.count).modify(_ + 1)

val Xor.Right(json) = parse("""
  { "x" : { "y" : [0, 1, { "foo" : { "count" : 3  }, "s" : "abcde" }] } }
""")

And then:

scala> json
res0: io.circe.Json =
{
  "x" : {
    "y" : [
      0,
      1,
      {
        "foo" : {
          "count" : 3
        },
        "s" : "abcde"
      }
    ]
  }
}

scala> incrementCount(json)
res1: io.circe.Json =
{
  "x" : {
    "y" : [
      0,
      1,
      {
        "s" : "abcde",
        "foo" : {
          "count" : 4
        }
      }
    ]
  }
}

def at(i: Int): JsonPath =
JsonPath(opt.composePrism(jsonArray).composeOptional(index(i)))

def as[A](implicit decode: Decoder[A], encode: Encoder[A]): Optional[Json, A] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that as is not lawful because decoder is not injective e.g.

case class Point(x: Int, y: Int)

val decoder: Decoder[Point] = ...
decoder.decodeJson(obj("x" -> int(1), "y" -> int(2))) == decoder.decodeJson(obj("x" -> int(1), "y" -> int(2), "z" -> int(5))) 

@julien-truffaut
Copy link
Contributor

You can upgrade monocle to 1.2.0-M2 and define a Plated instance

@travisbrown
Copy link
Member Author

I'm going to merge this when it's green on the understanding that the JsonPath API is subject to change.

travisbrown added a commit that referenced this pull request Nov 25, 2015
Initial sketch of optics module
@travisbrown travisbrown merged commit 81a9206 into master Nov 25, 2015
@travisbrown travisbrown deleted the topic/optics branch November 30, 2015 19:43
@dwijnand
Copy link
Contributor

The readme brought me here ("We are likely to add an experimental optics subproject in 0.3.0"), so given this is merged I think the readme should be updated.

julienrf pushed a commit to scalacenter/circe that referenced this pull request May 13, 2021
Don't define charBuilder where it's unneeded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants