Giter Club home page Giter Club logo

jsonpp's Introduction

jsonpp

Build Status

jsonpp is a header-only JSON parser and writer that is currently in development. It is a semi-strict parser that throws exceptions for errors.

jsonpp is licensed with the MIT license.

Features

  • Easy to use with a simple API.
  • No special null, array, or object types.
    • json::null is a type alias to std::nullptr_t.
    • json::array is std::vector<json::value>.
    • json::object is std::map<std::string, json::value>.
  • Decently fast.
  • No dependencies, only the standard library and a C++11 compiler.

Documentation

Documentation is an on going process and can be found here. Amongst documentation you can also find examples.

Example usage

Parsing

#include <jsonpp/parser.hpp>
#include <iostream>

int main() {
    json::parser p;
    json::value v;
    try {
        p.parse("[null, \"hello\", 10.0]", v);
        if(v.is<json::array>()) {
            for(auto&& val : v.as<json::array>()) {
                std::cout << val.as<std::string>("stuff");
            }
        }
    }
    catch(const std::exception& e) {
        std::cerr << e.what() << '\n';
    }
}

Output:

stuff hello stuff

Writing

#include <jsonpp/value.hpp>
#include <iostream>

int main() {
    json::value v = { nullptr, "hello", 10 };
    json::object o = {
        { "key", "value" },
        { "key2", 2 },
        { "key3", nullptr }
    };
    json::dump(std::cout, o);
}

Output:

{
    "key": "value",
    "key2": 2,
    "key3": null
}

Quirks and Specification

  • NaN and inf are currently allowed.
  • Comments, e.g. // stuff is planned to be supported in the future.
  • The parser is not destructive.
  • The parser is recursive descent.
  • Numbers are stored in a double just like JSON but v.as<int> and friends work with caution.
  • String is expected to be in UTF-8.
  • Some errors are not caught but effort has been made to catch a lot of errors.

jsonpp's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsonpp's Issues

is<T> for non-valid T is a compiler error

Essentially the title.

Rather than returning false like it should do, it just fails to compile instead making it a hassle for generic programming. This also applies to as<T>() though I'm not sure what the course of action should be for that.

Example:

#include <jsonpp.hpp>

struct pod {};

int main() {
    json::value x;
    return x.is<pod>();
}

Expected: return 0; equivalent.
Actual: Compiler error.

Add a way to prettyprint json values.

At the moment, json::value has a to_string member function that essentially gives a minimised JSON. That's good for some people, but there should be a way to get a properly "prettified" JSON.

README examples do not build

These are the errors when compiling the first example:

a.cpp: In function 'int main()':
a.cpp:5:18: error: missing template arguments before 'p'
     json::parser p;
                  ^
a.cpp:8:9: error: 'p' was not declared in this scope
         p.parse("[null, \"hello\", 10.0]", v);

Cicada says it "should be json::parse(...) instead of p.parse, and no constructing parser p;".

VS2013 does not support defaulting constructors with exception specifiers

Regarding the noexcept fix for VS2013, explicitly defaulted constructors marked as JSONPP_NOEXCEPT will fail to compile.

For example:

format_options() JSONPP_NOEXCEPT = default;

Expands as:

format_options() throw() = default;

Which fails to compile:

error C2610: 'json::format_options::format_options(void) throw()' : is not a special member function which can be defaulted exception specification is not allowed

to_json mechanism easily breakable by implicit constructors

Out of the box types supported by the dump mechanism can cause overload resolution issues if other types that are implicitly constructible/convertible from the out of the box types are thrown into the to_json overload pool.

Consider the following code snippet:

struct jsonpp_breaker {
    jsonpp_breaker( nullptr_t ) {

    }
};

json::value to_json( jsonpp_breaker breaker ) {
    return json::value(1);
}

int main( int argc, const char* const argv[] ) {

    std::string s = json::dump_string( nullptr );

}

In Visual Studio 2015 (RC), this makes the internal call to json::dump fail due to ambiguous overloads. Upon inspection of the internals, it seems like the Enable/DisableIfs are too lenient when it comes to evaluating whether to_json is acceptable: things that collide with the core serialized types (like nullptr constructors and friends) will trigger ambigious overload errors.

One implementation idea is to use a more sophisticated overloading mechanism or use a templated enable-if-friendly struct dumper<T, ...> to capture appropriate types when considering which dump function to use (it's default case should use the has_to_json<T> enable_if and provide a clean static_assert when that fails, and otherwise call whatever to_json is available).

Support for VS2013

A couple of changes required (thanks to Cicada of Lounge<C++>):

  • No using inline namespace.
    • Solution: Take them out completely (unfortunately)
  • No using noexcept.
    • Solution: Hide it behind a macro.
  • Removing using alternative token keywords as those require an extra switch for those using it (e.g. ! instead of not).
    • Solution: Include <ciso646> when using them or remove them completely.

Apparently that's all needed to get it working.

Nested type support for as/is

It would improve usability if we could specify nested type arguments as legal types in as/is. For example, as<std::vector<std::string>>, or as<std::map<std::string, std::vector<double>>>, rather than unpacking manually for each nested type.

Support a way to serialise objects to JSON

At the moment there's no way to turn a good ol' C++ class into JSON.

Ideally, there should be a way to turn a JSON string into a C++ object too, but that's too much work for something that could be provided by the user themselves so it's outside of the scope for this for now and probably outside the realm of possibility.

A good idea would be to have a to_json free function that takes in the custom type. The to_json function should return json::value that way it interacts with the API already in place.

to_string does not properly dump real JSON.

Since it doesn't dump real JSON, it's probably not a good way to dump JSON. So it should probably be removed or renamed for a better API.

The reason it doesn't dump real JSON is because when dumping strings, it ignores the \uxxxx literals and even the escape sequences which makes it wrong.

It might be worth looking into how Python does JSON dumping. This allows it to be relevant to issue #5.

Behaviour of operator[] is unintuitive

Currently, you return an rvalue from operator[], not an lvalue. Furthermore, operator= is not banned on rvalues as it should be. This leads to the exceedingly unintuitive behaviour where

json::value v;
v["thing"] = "string";

does not actually modify v at all, but silently leaves it unchanged.

I think that either supporting this use of operator[], or making it a compiler error, would be useful.

Add json::value_cast<T>

As an alternative to v.as<T>() we should be able to specify json::value_cast<T>(v).

This allows for removal of the template keyword in generic contexts, i.e. v.template as<T>().

Another overload for default parameters if it doesn't exist is fine too.

Parse comments.

The JSON spec doesn't allow comments but the parser shouldn't mind it.

Single line comments, e.g. // stuff and multi line comments e.g. /* */ should be fine.

Better conformance

Need to pass the conformance test suite from json.org

Currently the implementation that checks for leading zeroes disregards the possibility of the next value being the a decimal or a scientific notation initiative. That will need to be fixed along with other conformance issues.

Documentation

There's no documentation atm. Would be cool to have some basic documentation of the interface in the wiki or a markdown file.

Static assertions for as/is

I've noticed that when calling as or is with a type that they do not support, you get a runtime exception, even though you provide distinct overloads for this condition that just throw. It would be nice if this was replaced with a static_assert.

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.