All Projects → haskell-waargonaut → Waargonaut

haskell-waargonaut / Waargonaut

Licence: other
JSON decoding/encoding/manipulation library.

Programming Languages

haskell
3896 projects

Projects that are alternatives of or similar to Waargonaut

Spotify Json
Fast and nice to use C++ JSON library.
Stars: ✭ 145 (+76.83%)
Mutual labels:  json, json-parser, json-serialization
Mir Ion
WIP, use libmir/asdf package for now
Stars: ✭ 78 (-4.88%)
Mutual labels:  json, json-parser, json-serialization
Jsondoc
JSON object for Delphi based on IUnknown and Variant
Stars: ✭ 20 (-75.61%)
Mutual labels:  json, json-parser, json-serialization
Fastjson
A fast JSON parser/generator for Java.
Stars: ✭ 23,997 (+29164.63%)
Mutual labels:  json, json-parser, json-serialization
Easyjson
Fast JSON serializer for golang.
Stars: ✭ 3,512 (+4182.93%)
Mutual labels:  json, json-parser, json-serialization
Json Dry
🌞 JSON-dry allows you to serialize & revive objects containing circular references, dates, regexes, class instances,...
Stars: ✭ 214 (+160.98%)
Mutual labels:  json, json-parser, json-serialization
Spray Json
A lightweight, clean and simple JSON implementation in Scala
Stars: ✭ 917 (+1018.29%)
Mutual labels:  json, json-parser, json-serialization
Thorsserializer
C++ Serialization library for JSON
Stars: ✭ 241 (+193.9%)
Mutual labels:  json, json-parser, json-serialization
Jsoncons
A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON
Stars: ✭ 400 (+387.8%)
Mutual labels:  json, json-parser, json-serialization
Json
JSON for Modern C++
Stars: ✭ 27,824 (+33831.71%)
Mutual labels:  json, json-parser, json-serialization
Jsonpath Rs
JSONPath for Rust
Stars: ✭ 31 (-62.2%)
Mutual labels:  json, json-parser
Eminim
JSON serialization framework for Nim, works from a Stream directly to any type and back. Depends only on stdlib.
Stars: ✭ 32 (-60.98%)
Mutual labels:  json, json-serialization
Flatjson
A fast JSON parser (and builder)
Stars: ✭ 39 (-52.44%)
Mutual labels:  json, json-parser
Xml Js
Converter utility between XML text and Javascript object / JSON text.
Stars: ✭ 874 (+965.85%)
Mutual labels:  json, json-parser
Parson
Lightweight JSON library written in C.
Stars: ✭ 965 (+1076.83%)
Mutual labels:  json, json-parser
Djson
Fast Go decoder for dynamic JSON
Stars: ✭ 588 (+617.07%)
Mutual labels:  json, json-parser
Univalue
High performance RAII C++ JSON library and universal value object class
Stars: ✭ 46 (-43.9%)
Mutual labels:  json, json-parser
Gofasion
A lightweight json parsing library for golang.
Stars: ✭ 52 (-36.59%)
Mutual labels:  json, json-parser
Lazyjson
A very fast, very lazy JSON parser for Java.
Stars: ✭ 55 (-32.93%)
Mutual labels:  json, json-parser
Njson
Unmarshal/Decode nested JSON by JSON Path
Stars: ✭ 61 (-25.61%)
Mutual labels:  json, json-parser

CSIRO's Data61 Logo

Build Status

Waargonaut

Flexible, precise, and efficient JSON decoding/encoding library. This package provides a plethora of tools for decoding, encoding, and manipulating JSON data.

Features

  • Fully RFC compliant, with property based testing used to ensure the desired invariants are preserved.

  • Encoders and Decoders are values, they are not tied to a typeclass and as such you are not tied to a single interpretation of how a particular type "should" be handled.

  • No information is discarded on parsing. Trailing whitespace, and any formatting whitespace (carriage returns etc) are all preserved.

  • A history keeping zipper is used for Decoding, providing precise control of how you decode your JSON data. With informative error messages if things don't go according to plan.

  • Flexible and expressive Decoder & Encoder functions let you parse and build the JSON structures you require, with no surprises.

  • BYO parsing library, the parser built into Waargonaut does not tie you to a particular parsing library. With the caveat that your parsing library must have an instance of CharParsing from the parsers package.

  • Generic functions are provided to make the creation of Encoders and Decoders are bit easier. However these are tied to typeclasses, so they do come with some assumptions.

  • Lenses, Prisms, and Traversals are provided to allow you to investigate and manipulate the JSON data structures to your hearts content, without breaking the invariants.

  • The awesome work on succinct data structures by John Ky and Haskell Works is used to power the decoder. Providing the same zipper capabilities and property based guarantees, but with all the speed and efficiency capabilities that succinct data structures have to offer.

Example

  • Data Structure:
data Image = Image
  { _imageWidth    :: Int
  , _imageHeight   :: Int
  , _imageTitle    :: Text
  , _imageAnimated :: Bool
  , _imageIDs      :: [Int]
  }
  • Encoder:
encodeImage :: Applicative f => Encoder f Image
encodeImage = E.mapLikeObj $ \img ->
    E.intAt "Width" (_imageWidth img)
  . E.intAt "Height" (_imageHeight img)
  . E.textAt "Title" (_imageTitle img)
  . E.boolAt "Animated" (_imageAnimated img)
  . E.listAt E.int "IDs" (_imageIDs img)
  • Decoder:
imageDecoder :: Monad f => D.Decoder f Image
imageDecoder = D.withCursor $ \curs -> do
  -- Move down into the JSON object.
  io <- D.down curs
  -- We need individual values off of our object,
  Image
    <$> D.fromKey "Width" D.int io
    <*> D.fromKey "Height" D.int io
    <*> D.fromKey "Title" D.text io
    <*> D.fromKey "Animated" D.bool io
    <*> D.fromKey "IDs" (D.list D.int) io

Zippers

Waargonaut uses zippers for its decoding which allows for precise control in how you interrogate your JSON input. Take JSON structures and decode them precisely as you require:

Input:
["a","fred",1,2,3,4]
Data Structure:
data Foo = Foo (Char,String,[Int])
Decoder:

The zipper starts the very root of the JSON input, we tell it to move 'down' into the first element.

fooDecoder :: Monad f => Decoder f Foo
fooDecoder = D.withCursor $ \cursor -> do
  fstElem <- D.down cursor

From the first element we can then decode the focus of the zipper using a specific decoder:

  aChar <- D.focus D.unboundedChar fstElem

The next thing we want to decode is the second element of the array, so we move right one step or tooth, and then attempt to decode a string at the focus.

  aString <- D.moveRight1 fstElem >>= D.focus D.string

Finally we want to take everything else in the list and combine them into a single list of Int values. Starting from the first element, we move right two positions (over the char and the string elements), then we use one of the provided decoder functions that will repeatedly move in a direction and combine all of the elements it can until it can no longer move.

  aIntList <- D.moveRightN 2 fstElem >>= D.rightwardSnoc [] D.int

Lastly, we build the Foo using the decoded values.

  pure $ Foo (aChar, aString, aIntList)

The zipper stores the history of your movements, so any errors provide information about the path they took prior to encountering an error. Making debugging precise and straight-forward.

Property Driven Development

This library is built to parse and produce JSON in accordance with the RFC 8259 standard. The data structures, parser, and printer are built to satify the Round Trip Property:

Which may be expressed using the following pseudocode:

parse . print = id

This indicates that any JSON produced by this library will be parsed back in as the exact data structure that produced it. This includes whitespace such as carriage returns and trailing whitespace. There is no loss of information.

There is also this property, again in pseudocode:

print . parse . print = print

This states that the printed form of the JSON will not change will be identical after parsing and then re-printing. There is no loss of information.

This provides a solid foundation to build upon.

NB: The actual code will of course return values that account for the possibility of failure. Computers being what they are.

TODO(s)

In no particular order...

  • [ ] improve/bikeshed encoding object api
  • [ ] gather feedback on tests/benchmarks that matter
  • [ ] provide testing functions so users can be more confident in their Encoder/Decoder construction
  • [x] (feedback required) documentation in the various modules to explain any weirdness or things that users may consider to be 'missing' or 'wrong'.
  • [x] (mostly) provide greater rationale behind lack of reliance in typeclasses for encoding/decoding
  • [ ] provide functions to add preset whitespace layouts to encoded json.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].