| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- #pragma once
- #include <type_traits>
- #include <json/value.h>
- #include <jvalidate/adapter.h>
- #include <jvalidate/detail/number.h>
- #include <jvalidate/detail/simple_adapter.h>
- #include <jvalidate/enum.h>
- namespace jvalidate::adapter {
- template <typename JSON> class JsonCppAdapter;
- template <> struct AdapterTraits<Json::Value> {
- template <typename JSON> using Adapter = adapter::JsonCppAdapter<JSON>;
- using ConstAdapter = adapter::JsonCppAdapter<Json::Value const>;
- static Json::Value const & const_empty() {
- static Json::Value const g_value;
- return g_value;
- }
- };
- template <typename JSON> class JsonCppObjectAdapter : public detail::SimpleObjectAdapter<JSON> {
- public:
- using JsonCppObjectAdapter::SimpleObjectAdapter::SimpleObjectAdapter;
- bool contains(std::string const & key) const { return this->const_value().isMember(key); }
- JsonCppAdapter<JSON> operator[](std::string const & key) const {
- return this->value() ? &(*this->value())[key] : nullptr;
- }
- void assign(std::string const & key, Const const & frozen) const
- requires(not std::is_const_v<JSON>)
- {
- (*this)[key].assign(frozen);
- }
- };
- template <typename JSON> class JsonCppAdapter final : public detail::SimpleAdapter<JSON> {
- public:
- using JsonCppAdapter::SimpleAdapter::SimpleAdapter;
- Type type() const {
- using jvalidate::detail::fits_in_integer;
- switch (const_value().type()) {
- case Json::nullValue:
- return Type::Null;
- case Json::booleanValue:
- return Type::Boolean;
- case Json::realValue:
- // Not strictly necessary - Validation code will safely handle this too
- return fits_in_integer(const_value().asDouble()) ? Type::Integer : Type::Number;
- case Json::stringValue:
- return Type::String;
- case Json::arrayValue:
- return Type::Array;
- case Json::objectValue:
- return Type::Object;
- case Json::intValue:
- return Type::Integer;
- case Json::uintValue:
- return fits_in_integer(const_value().asUInt64()) ? Type::Integer : Type::Number;
- }
- }
- bool as_boolean() const { return const_value().asBool(); }
- int64_t as_integer() const { return const_value().asInt64(); }
- double as_number() const { return const_value().asDouble(); }
- std::string as_string() const { return const_value().asString(); }
- JsonCppObjectAdapter<JSON> as_object() const { return value(); }
- static std::string key(auto it) { return it.key().asString(); }
- using detail::SimpleAdapter<JSON>::assign;
- void assign(Adapter const & adapter) const
- requires(not std::is_const_v<JSON>)
- {
- switch (adapter.type()) {
- case Type::Null:
- *value() = Json::nullValue;
- return;
- case Type::Boolean:
- *value() = adapter.as_boolean();
- return;
- case Type::Integer:
- *value() = adapter.as_integer();
- return;
- case Type::Number:
- *value() = adapter.as_number();
- return;
- case Type::String:
- *value() = adapter.as_string();
- return;
- case Type::Array:
- adapter.apply_array([this, index = 0](Adapter const & elem) mutable {
- JsonCppAdapter((*value())[index]).assign(elem);
- ++index;
- return Status::Accept;
- });
- return;
- case Type::Object:
- adapter.apply_object([this](std::string const & key, Adapter const & elem) {
- JsonCppAdapter((*value())[key]).assign(elem);
- return Status::Accept;
- });
- return;
- }
- }
- public:
- using JsonCppAdapter::SimpleAdapter::const_value;
- using JsonCppAdapter::SimpleAdapter::value;
- };
- }
|