Git Product home page Git Product logo

diffson's Introduction

Gnieh Diffson Build Status Code Coverage Maven Central

A scala implementation of the RFC-6901 and RFC-6902. It also provides methods to compute diffs between two Json values that produce valid Json patches.

Table of Contents

Getting Started

This library is published in the Maven Central Repository and is compiled against scala 2.11. You can add it to your sbt project by putting this line to your build description:

libraryDependencies += "org.gnieh" %% "diffson" % "2.0.2"

If you are using maven, add the following dependency to your pom.xml:

<dependency>
  <groupId>org.gnieh</groupId>
  <artifactId>diffson_${scala.version}</artifactId>
  <version>2.0.2</version>
</dependency>

Snapshot versions

Snapshot versions are published:

libraryDependencies += "org.gnieh" %% "diffson-spray-json" % "2.1.0-SNAPSHOT"
libraryDependencies += "org.gnieh" %% "diffson-play-json" % "2.1.0-SNAPSHOT"
libraryDependencies += "org.gnieh" %% "diffson-circe" % "2.1.0-SNAPSHOT"

If you are using maven, add the following dependency to your pom.xml:

<dependency>
  <groupId>org.gnieh</groupId>
  <artifactId>diffson_${scala.version}-play-json</artifactId>
  <version>2.1.0-SNAPSHOT</version>
</dependency>

These versions are built for Scala 2.11 and 2.12 when the underlying json library is already published for 2.12.

Json Library

Diffson was first developped for spray-json, however, it is possible to use it with any json library of your linking. The only requirement is to have a DiffsonInstance for your json library.

At the moment, diffson provides two instances for spray-json and Play! Json. To use these implementations you need to link with the correct module and import the instance:

// spray-json
import gnieh.diffson.sprayJson._
// play-json
import gnieh.diffson.playJson._

You also need to add the library in your classpath, as they are marked as provided by diffson to avoid depending on all json libraries when using diffson.

If you want to add support for your favorite Json library, all you need to do is to implement the gnieh.diffson.DiffsonInstance class, which provide the JsonProvider for the specific library. Contribution of new Json libraries in this repository are more than welcome.

Basic Usage

Although the library is quite small and easy to use, here comes a summary of its basic usage.

There are three different entities living in the gnieh.diffson package:

  • JsonPointer which allows to parse and manipulate Json pointers as defined in RFC-6901,
  • JsonPatch which allows to parse, create and apply Json patches as defined in RFC-6902,
  • JsonDiff which allows to compute the diff between two Json values and create Json patches.

Basically if one wants to compute the diff between two Json objects, on can execute the following:

val json1 = """{
              |  "a": 1,
              |  "b": true,
              |  "c": "test"
              |}""".stripMargin

val json2 = """{
              |  "a": 6,
              |  "c": "test2",
              |  "d": false
              |}""".stripMargin

val patch = JsonDiff.diff(json1, json2, false)

println(patch)

which will print the following in the console:

[{
  "op":"replace",
  "path":"/a",
  "value":6
},{
  "op":"remove",
  "path":"/b"
},{
  "op":"replace",
  "path":"/c",
  "value":"test2"
},{
  "op":"add",
  "path":"/d",
  "value":false
}]

You can then apply the patch to json1:

val json3 = patch(json1)
println(json3)

which prints something like:

{
  "d":false,
  "c":"test2",
  "a":6
}

which we can easily verify is the same as json2 modulo reordering of fields.

You may also only want to apply existing patches:

val raw = """[
            |  {
            |    "op": "test",
            |    "path": "/a",
            |    "value": 4
            |  }
            |]""".stripMargin

val patch = JsonPatch.parse(raw)

val json1 = """{ "a": 4 }"""
val json2 = """{ "a": 7 }"""
patch(json1) // ok json1 is returned unchanched
patch(json2) // throws PatchException

Remembering old values

The diff method takes three parameter. The third one indicates whether the generated patch remembers removed and replaced values. When set to true, the Replace and Remove operations take an extra field named old giving the old value. The RFC does not define these fields, but it does not fordbid either to add extra fields. Hence, generated patches can still be interpreted by third party implementations.

Patches as Collections of Operations

Patches may be seen as collections of operations on which you may which to apply some typical collection functions such as map, flatMap, filtering, folding, ...

val patch: JsonPatch = ...

val patch2: JsonPatch =
  for(op @ Add("my" :: "prefix" :: _, _) <- patch)
    yield op

Technical Details

The implementation uses spray-json to manipulate Json objects.

The diff between two arrays is computed by using the Patience Diff algorithm to compute the LCS between both arrays, which is quite simple to implement.

However one can replace the implementation by any other algorithm that implements the gnieh.diffson.Lcs trait, e.g.:

val diff = new JsonDiff(new MyLcsAlgorithm)

then use diff in lieu of JsonDiff in the first usage example.

diffson's People

Contributors

dyk avatar ejao1 avatar guersam avatar kolloch avatar kring avatar osidorkin avatar radusw avatar satabin avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.