diff --git a/data_model/json/all.hpp b/data_model/json/all.hpp new file mode 100644 index 000000000..eb179eadd --- /dev/null +++ b/data_model/json/all.hpp @@ -0,0 +1,14 @@ +#ifndef JSON_ALL_HPP +#define JSON_ALL_HPP + +#include "array.hpp" +#include "bool.hpp" +#include "integral.hpp" +#include "json.hpp" +#include "null.hpp" +#include "object.hpp" +#include "primitive.hpp" +#include "real.hpp" +#include "string.hpp" + +#endif diff --git a/data_model/json/array.hpp b/data_model/json/array.hpp new file mode 100644 index 000000000..bd0ef1a76 --- /dev/null +++ b/data_model/json/array.hpp @@ -0,0 +1,84 @@ +#ifndef JSON_ARRAY_HPP +#define JSON_ARRAY_HPP + +#include +#include +#include + +#include "../utilities/utils.hpp" + +#include "json.hpp" + +namespace json +{ + +class Array final : public Json +{ +public: + Array() {} + + template + Array(It first, It last) + : elements(first, last) {} + + Array(std::initializer_list elements) + : elements(elements) {} + + virtual bool is_array() const; + + size_t size() const; + + Array& push(const std::shared_ptr& element); + + const spJson& operator[](size_t i) const; + spJson operator[](size_t i); + + virtual operator std::string() const; + +private: + std::vector elements; +}; + +bool Array::is_array() const +{ + return true; +} + +size_t Array::size() const +{ + return elements.size(); +} + +Array& Array::push(const spJson& element) +{ + assert(element); + + elements.push_back(element); + return *this; +} + +const spJson& Array::operator[](size_t i) const +{ + return elements[i]; +} + +spJson Array::operator[](size_t i) +{ + return elements[i]; +} + +Array::operator std::string() const +{ + std::vector xs; + + std::transform(elements.begin(), elements.end(), std::back_inserter(xs), + [](const spJson& element) { + return static_cast(*element); + }); + + return "[" + utils::intercalate(xs.begin(), xs.end(), ",") + "]"; +} + +} + +#endif diff --git a/data_model/json/bool.hpp b/data_model/json/bool.hpp new file mode 100644 index 000000000..f91d1f20f --- /dev/null +++ b/data_model/json/bool.hpp @@ -0,0 +1,33 @@ +#ifndef JSON_BOOL_HPP +#define JSON_BOOL_HPP + +#include "primitive.hpp" + +namespace json { + +class Bool final : public Primitive +{ +public: + Bool() {} + + Bool(bool value) + : Primitive(value) {} + + virtual bool is_boolean() const; + + virtual operator std::string() const; +}; + +bool Bool::is_boolean() const +{ + return true; +} + +Bool::operator std::string() const +{ + return value == true ? "true" : "false"; +} + +} + +#endif diff --git a/data_model/json/integral.hpp b/data_model/json/integral.hpp new file mode 100644 index 000000000..fd961ebbd --- /dev/null +++ b/data_model/json/integral.hpp @@ -0,0 +1,33 @@ +#ifndef JSON_INTEGRAL_HPP +#define JSON_INTEGRAL_HPP + +#include "primitive.hpp" + +namespace json { + +class Integral final : public Primitive +{ +public: + Integral() {} + + Integral(int64_t value) + : Primitive(value) {} + + virtual bool is_integral() const; + + virtual operator std::string() const; +}; + +bool Integral::is_integral() const +{ + return true; +} + +Integral::operator std::string() const +{ + return std::to_string(value); +} + +} + +#endif diff --git a/data_model/json/json.hpp b/data_model/json/json.hpp new file mode 100644 index 000000000..f966b841a --- /dev/null +++ b/data_model/json/json.hpp @@ -0,0 +1,47 @@ +#ifndef JSON_JSON_HPP +#define JSON_JSON_HPP + +#include +#include +#include + +namespace json { + +class Json; + +typedef std::shared_ptr spJson; + +class Json +{ +public: + Json() {} + virtual ~Json() {} + + virtual bool is_object() const { return false; } + virtual bool is_array() const { return false; } + virtual bool is_real() const { return false; } + virtual bool is_integral() const { return false; } + virtual bool is_boolean() const { return false; } + virtual bool is_null() const { return false; } + + template T& as(); + template const T& as() const; + + virtual operator std::string() const = 0; +}; + +template +T& Json::as() +{ + return *dynamic_cast(this); +} + +template +const T& Json::as() const +{ + return *dynamic_cast(this); +} + +} + +#endif diff --git a/data_model/json/null.hpp b/data_model/json/null.hpp new file mode 100644 index 000000000..982363e4e --- /dev/null +++ b/data_model/json/null.hpp @@ -0,0 +1,30 @@ +#ifndef JSON_NULL_HPP +#define JSON_NULL_HPP + +#include "json.hpp" + +namespace json { + +class Null final : public Json +{ +public: + Null() {} + + virtual bool is_null() const; + + virtual operator std::string() const; +}; + +bool Null::is_null() const +{ + return true; +} + +Null::operator std::string() const +{ + return "null"; +} + +} + +#endif diff --git a/data_model/json/object.hpp b/data_model/json/object.hpp new file mode 100644 index 000000000..5ecbbc378 --- /dev/null +++ b/data_model/json/object.hpp @@ -0,0 +1,106 @@ +#ifndef JSON_OBJECT_HPP +#define JSON_OBJECT_HPP + +#include + +#include +#include +#include +#include +#include + +#include "../utilities/utils.hpp" + +#include "json.hpp" + +namespace json { + +typedef std::pair const_kv_pair_t; +typedef std::pair kv_pair_t; + +class Object; + +typedef std::shared_ptr spObject; + +class Object : public Json +{ +public: + Object() {} + + Object(std::initializer_list elements) + : props(elements) {} + + virtual bool is_object() const; + + const spJson& at(const std::string& key) const; + spJson at(const std::string& key); + + const spJson& operator[](const std::string& key) const; + spJson operator[](const std::string& key); + + Object& put(const std::string& key, spJson value); + + Object& operator<<(const kv_pair_t& kv_pair); + + virtual operator std::string() const; + +protected: + std::map props; +}; + +bool Object::is_object() const +{ + return true; +} + +const spJson& Object::at(const std::string& key) const +{ + return props.at(key); +} + +spJson Object::at(const std::string& key) +{ + return props.at(key); +} + +const spJson& Object::operator[](const std::string& key) const +{ + return this->at(key); +} + +spJson Object::operator[](const std::string& key) +{ + return this->at(key); +} + +Object& Object::put(const std::string& key, spJson value) +{ + assert(value); + + props[key] = value; + return *this; +} + +Object& Object::operator<<(const kv_pair_t& kv_pair) +{ + return this->put(std::get<0>(kv_pair), std::get<1>(kv_pair)); +} + +Object::operator std::string() const +{ + if(props.empty()) + return "{}"; + + std::vector xs; + + std::transform(props.begin(), props.end(), std::back_inserter(xs), + [](const kv_pair_t& kvp) { + return "\"" + kvp.first + "\":" + static_cast(*kvp.second); + }); + + return "{" + utils::intercalate(xs.begin(), xs.end(), ",") + "}"; +} + +} + +#endif diff --git a/data_model/json/primitive.hpp b/data_model/json/primitive.hpp new file mode 100644 index 000000000..a0da326a8 --- /dev/null +++ b/data_model/json/primitive.hpp @@ -0,0 +1,29 @@ +#ifndef JSON_PRIMITIVE +#define JSON_PRIMITIVE + +#include "json.hpp" + +namespace json { + +template +class Primitive : public Json +{ +public: + Primitive() {} + + Primitive(const T& value) + : value(value) {} + + T get() const { return value; } + void set(T value) { this->value = value; } + + operator T() const { return this->get(); } + +protected: + T value; +}; + + +} + +#endif diff --git a/data_model/json/real.hpp b/data_model/json/real.hpp new file mode 100644 index 000000000..e3e5d3eff --- /dev/null +++ b/data_model/json/real.hpp @@ -0,0 +1,33 @@ +#ifndef JSON_REAL_HPP +#define JSON_REAL_HPP + +#include "primitive.hpp" + +namespace json { + +class Real final : public Primitive +{ +public: + Real() {} + + Real(float value) + : Primitive(value) {} + + virtual bool is_real() const; + + virtual operator std::string() const; +}; + +bool Real::is_real() const +{ + return true; +} + +Real::operator std::string() const +{ + return std::to_string(value); +} + +} + +#endif diff --git a/data_model/json/string.hpp b/data_model/json/string.hpp new file mode 100644 index 000000000..5fdd5b27d --- /dev/null +++ b/data_model/json/string.hpp @@ -0,0 +1,34 @@ +#ifndef JSON_STRING_HPP +#define JSON_STRING_HPP + +#include "primitive.hpp" + +namespace json +{ + +class String final : public Primitive +{ +public: + String() {} + + String(const std::string& value) + : Primitive(value) {} + + virtual bool is_string() const; + + virtual operator std::string() const; +}; + +bool String::is_string() const +{ + return true; +} + +String::operator std::string() const +{ + return "\"" + value + "\""; +} + +} + +#endif