This library, libvariant, provides a class called Variant. This class is a discriminating union that can contain one of the following values:
- a null, or no type
- a boolean value
- an unsigned integer
- a signed integer
- a floating point value
- a string value
- a reference to a map of string to Variant
- a reference to a list of Variant
- a reference to a iovec list (Blob)
- Scripting language like variable (Variant) in C++ (with all the upsides and downsides that implies).
- JSON serialization.
- YAML serialization. Deserialization ignores most tags.
- plist serialization.
- Schema validation based on json-schema.
- Schema lookup can be set to use libcurl to fetch remote URLs.
- A simple argument parsing (ArgParse) class that produces a Variant from a programs arguments.
- Experimental msgpack serialization using msgpack-c (disabled by default).
- JSONPointer (RFC6901) and JSONPatch (RFC6902) implementations.
Changes for the 1.0.1 release
- Cleaned up static data initialization, will no long call abort.
- Fixed a bug related to proxy resolution when performing additional path resolution.
- Added an ignore_payload and payload_length parameter to the payload serializer helpers.
- Implemented proper JSONPointer lookup routines and changed the schema lookup to use them.
- Modified ArgParse so that positional argument can be specified in loaded configuration files.
- Added a make dist build target.
- Other minor fixes.
Under the hood, Variant uses an explicit vtable to implement the different behaviors with the same interface. The vtable has more types than the standard types listed above. The additional types are a reference and proxy type. There is also a class that is exposed to the user as VariantRef. Several of the functions that return a Variant return a VariantRef. A VariantRef is a Variant so const Variant & can bind to a VariantRef. But, in general Variant& cannot bind to VariantRef as all functions that return VariantRef, return it by value. This means that if you want a function that takes a non-const Variant as a parameter to be used as an output parameter, the function must take a VariantRef by value. VariantRef can be constructed from a Variant as well, so such a function can take either a VariantRef or Variant.
libvariant is publicly hosted here.
This project uses CMake to generate a build system. Consult the CMake documentation for your preferred build system generation.
Building on unix
The default build system generated by CMake on unix is to use make. To build with make simply perform the following commands where you would like the build output:
cmake /path/to/libvariant/sources/ make
And to install: make install
The cmake configuration files use the standard cmake variables.
libvariant is optionally dependent on the following libraries
- libyaml to provide yaml serialization
- libxml2 to provide plist serialization
- libcurl to provide schema web lookup
- msgpack-c for the experimental msgpack serialization
CMake variables are provided to override the default dependency behavior.
This library also contains a schema validator. The language of the schema when serialized as JSON is json-schema. See json-schema.org for details about json-schema. Note the validator in this library uses the version 4 dialect. The schema for the version 4 dialect can be acquired from http://json-schema.org/draft-04/schema
Other than a validator, there is a function to add the schema defaults to a Variant. This function goes through the schema and attempts to add the defaults specified in it to the Variant provided if a value is not already present. There are several constructs that it ignores such as not.
Data generation from schemas
Generating a valid set of data from schema is an interesting idea, and can be useful for testing purposes. But this problem is rather difficult in general. For example, the anyOf, oneOf, allOf, and not constructs in a schema mean that it is possible that the data generator must solve a satisfiability problem. It is well known that non-trivial satisfiability problems are NP complete. Despite this there does exists several random data generators (but they can fail to produce output or can produce output that does not validate). The following are links to two of the generators I was able to find.
- [http://schematic-ipsum.herokuapp.com/] - a web app
- [https://github.com/andreineculau/json-schema-random] - requires nodejs
The main API is documented in the source code using the Doxygen format. The generated html documentation is served on the web at http://gallen.bitbucket.org/libvariant-docs.
If you have doxygen installed, you can generate html documentation of the libvariant public interface from the source code with:
cd /path/to/build_dir cmake /path/to/libvariant make doc