JSON Voorhees
Killer JSON for C++
jsonv::formats Class Reference

Simply put, this class is a collection of extractor and serializer instances. More...

#include <jsonv/serialization.hpp>

Public Types

using list = std::vector< formats >
 

Public Member Functions

 formats ()
 Create a new, empty formats instance. More...
 
void extract (const std::type_info &type, const value &from, void *into, const extraction_context &context) const
 Extract the provided type from a value into an area of memory. More...
 
const extractorget_extractor (std::type_index type) const
 Get the extractor for the given type. More...
 
const extractorget_extractor (const std::type_info &type) const
 Get the extractor for the given type. More...
 
value to_json (const std::type_info &type, const void *from, const serialization_context &context) const
 Encode the provided value from into a JSON value. More...
 
const serializerget_serializer (std::type_index type) const
 Gets the serializer for the given type. More...
 
const serializerget_serializer (const std::type_info &type) const
 Gets the serializer for the given type. More...
 
void register_extractor (const extractor *, duplicate_type_action action=duplicate_type_action::exception)
 Register an extractor that lives in some unmanaged space. More...
 
void register_extractor (std::shared_ptr< const extractor >, duplicate_type_action action=duplicate_type_action::exception)
 Register an extractor with shared ownership between this formats instance and anything else. More...
 
void register_serializer (const serializer *, duplicate_type_action action=duplicate_type_action::exception)
 Register a serializer that lives in some managed space. More...
 
void register_serializer (std::shared_ptr< const serializer >, duplicate_type_action action=duplicate_type_action::exception)
 Register a serializer with shared ownership between this formats instance and anything else. More...
 
void register_adapter (const adapter *, duplicate_type_action action=duplicate_type_action::exception)
 Register an adapter that lives in some unmanaged space. More...
 
void register_adapter (std::shared_ptr< const adapter >, duplicate_type_action action=duplicate_type_action::exception)
 Register an adapter with shared ownership between this formats instance and anything else. More...
 
bool operator== (const formats &other) const
 Test for equality between this instance and other. More...
 
bool operator!= (const formats &other) const
 Test for inequality between this instance and other. More...
 

Static Public Member Functions

static formats defaults ()
 Get the default formats instance. More...
 
static formats global ()
 Get the global formats instance. More...
 
static formats set_global (formats)
 Set the global formats instance. More...
 
static formats reset_global ()
 Reset the global formats instance to defaults. More...
 
static formats coerce ()
 Get the coercing formats instance. More...
 
static formats compose (const list &bases)
 Create a new (empty) formats using the bases as backing formats. More...
 

Detailed Description

Simply put, this class is a collection of extractor and serializer instances.

Ultimately, formats form a directed graph of possible types to load. This allows you to compose formats including your application with any number of 3rd party libraries an base formats. Imagine an application that has both a user facing API and an object storage system, both of which speak JSON. When loading from the database, you would like strict type enforcement – check that when you say extract<int>(val), that val actually has kind::integer. When getting values from the API, you happily convert kind::string with the value "51" into the integer 51. You really don't want to have to write two versions of decoders for all of your objects: one which uses the standard checked value::as_integer and one that uses coerce_integer – you want the same object model.

To do this, you would create your object model (called my_app_formats in the chart) with the object models for your application-specific types. This can use any number of 3rd party libraries to get the job done. To make a functional formats, you would compose different formats instances into a single one. From there,

jsonv::formats get_api_formats()
{
static jsonv::formats instance = jsonv::formats::compose({ jsonv::formats::coerce(), get_app_formats() });
return instance;
}
jsonv::formats get_db_formats()
{
static jsonv::formats instance = jsonv::formats::compose({ jsonv::formats::defaults(), get_app_formats() });
return instance;
}
MyType extract_thing(const jsonv::value& from, bool from_db)
{
return jsonv::extract<MyType>(from, from_db ? get_db_formats() : get_api_formats());
}

Definition at line 321 of file serialization.hpp.

Constructor & Destructor Documentation

jsonv::formats::formats ( )

Create a new, empty formats instance.

By default, this does not know how to extract anything – not even the basic types like int64_t or std::string.

Member Function Documentation

static formats jsonv::formats::coerce ( )
static

Get the coercing formats instance.

This uses loose type-checking and behaves by the same rules as the coerce_ functions in coerce.hpp.

Note
This function actually returns a copy of the default formats, so modifications do not affect the actual instance.
static formats jsonv::formats::compose ( const list &  bases)
static

Create a new (empty) formats using the bases as backing formats.

This forms a directed graph of formats objects. When searching for an extractor or serializer, the formats is searched, then each base is searched depth-first left-to-right.

Parameters
basesIs the list of formats objects to use as bases for the newly-created formats. Order matters – the bases are searched left-to-right, so formats that are farther left take precedence over those more to the right.
Note
It is impossible to form an endless loop of formats objects, since the base of all formats are eventually empty. If there is an existing set of nodes \( k \) and each new format created with compose is in \( k+1 \), there is no way to create a link from \( k \) into \( k+1 \) and so there is no way to create a circuit.
static formats jsonv::formats::defaults ( )
static

Get the default formats instance.

This uses strict type-checking and behaves by the same rules as the value as_ member functions (as_integer, as_string, etc).

Note
This function actually returns a copy of the default formats, so modifications do not affect the actual instance.
void jsonv::formats::extract ( const std::type_info &  type,
const value from,
void *  into,
const extraction_context context 
) const

Extract the provided type from a value into an area of memory.

The context is passed to the extractor which performs the conversion. In general, this should not be used directly as it is quite painful to do so – prefer extraction_context::extract or the free function jsonv::extract.

Exceptions
no_extractorif an extractor for type could not be found.
const extractor& jsonv::formats::get_extractor ( std::type_index  type) const

Get the extractor for the given type.

Exceptions
no_extractorif an extractor for type could not be found.
const extractor& jsonv::formats::get_extractor ( const std::type_info &  type) const

Get the extractor for the given type.

Exceptions
no_extractorif an extractor for type could not be found.
const serializer& jsonv::formats::get_serializer ( std::type_index  type) const

Gets the serializer for the given type.

Exceptions
no_serializerif a serializer for type could not be found.
const serializer& jsonv::formats::get_serializer ( const std::type_info &  type) const

Gets the serializer for the given type.

Exceptions
no_serializerif a serializer for type could not be found.
static formats jsonv::formats::global ( )
static

Get the global formats instance.

By default, this is the same as defaults, but you can override it with set_global. The extract function uses this formats instance if none is provided, so this is convenient if your application only has one type of formats to use.

Note
This function actually returns a copy of the global formats, so modifications do not affect the actual instance. If you wish to alter the global formats, use set_global.
bool jsonv::formats::operator!= ( const formats other) const

Test for inequality between this instance and other.

The opposite of operator==.

bool jsonv::formats::operator== ( const formats other) const

Test for equality between this instance and other.

If two formats are equal, they are the exact same node in the graph. Even if one formats has the exact same types for the exact same extractors.

void jsonv::formats::register_adapter ( const adapter ,
duplicate_type_action  action = duplicate_type_action::exception 
)

Register an adapter that lives in some unmanaged space.

Exceptions
duplicate_type_errorif this formats instance already has either an extractor or serializer that serves the provided adapter::get_type and the duplicate_type_action is exception.
void jsonv::formats::register_adapter ( std::shared_ptr< const adapter ,
duplicate_type_action  action = duplicate_type_action::exception 
)

Register an adapter with shared ownership between this formats instance and anything else.

Exceptions
duplicate_type_errorif this formats instance already has either an extractor or serializer that serves the provided adapter::get_type the duplicate_type_action is exception.
void jsonv::formats::register_extractor ( const extractor ,
duplicate_type_action  action = duplicate_type_action::exception 
)

Register an extractor that lives in some unmanaged space.

Exceptions
duplicate_type_errorif this formats instance already has an extractor that serves the provided extractor::get_type and the duplicate_type_action is exception.
void jsonv::formats::register_extractor ( std::shared_ptr< const extractor ,
duplicate_type_action  action = duplicate_type_action::exception 
)

Register an extractor with shared ownership between this formats instance and anything else.

Exceptions
duplicate_type_errorif this formats instance already has an extractor that serves the provided extractor::get_type and the duplicate_type_action is exception.
void jsonv::formats::register_serializer ( const serializer ,
duplicate_type_action  action = duplicate_type_action::exception 
)

Register a serializer that lives in some managed space.

Exceptions
duplicate_type_errorif this formats instance already has a serializer that serves the provided serializer::get_type and the duplicate_type_action is exception.
void jsonv::formats::register_serializer ( std::shared_ptr< const serializer ,
duplicate_type_action  action = duplicate_type_action::exception 
)

Register a serializer with shared ownership between this formats instance and anything else.

Exceptions
duplicate_type_errorif this formats instance already has a serializer that serves the provided serializer::get_type and the duplicate_type_action is exception.
static formats jsonv::formats::reset_global ( )
static

Reset the global formats instance to defaults.

Returns
the previous value of the global formats instance.
static formats jsonv::formats::set_global ( formats  )
static

Set the global formats instance.

Returns
the previous value of the global formats instance.
value jsonv::formats::to_json ( const std::type_info &  type,
const void *  from,
const serialization_context context 
) const

Encode the provided value from into a JSON value.

The context is passed to the serializer which performs the conversion. In general, this should not be used directly as it is painful to do so – prefer serialization_context::to_json or the free function jsonv::to_json.

Exceptions
no_serializerif a serializer for type could not be found.

The documentation for this class was generated from the following file: