jsoncpp.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #pragma once
  2. #include <compare>
  3. #include <memory>
  4. #include <type_traits>
  5. #include <json/value.h>
  6. #include <jvalidate/adapter.h>
  7. #include <jvalidate/detail/simple_adapter.h>
  8. #include <jvalidate/enum.h>
  9. namespace jvalidate::adapter {
  10. template <typename JSON> class JsonCppAdapter;
  11. template <> struct AdapterTraits<Json::Value> {
  12. template <typename JSON> using Adapter = adapter::JsonCppAdapter<JSON>;
  13. using ConstAdapter = adapter::JsonCppAdapter<Json::Value const>;
  14. static Json::Value const & const_empty() {
  15. static Json::Value const g_value;
  16. return g_value;
  17. }
  18. };
  19. template <typename JSON> class JsonCppObjectAdapter : public detail::SimpleObjectAdapter<JSON> {
  20. public:
  21. using JsonCppObjectAdapter::SimpleObjectAdapter::SimpleObjectAdapter;
  22. bool contains(std::string const & key) const { return this->const_value().isMember(key); }
  23. JsonCppAdapter<JSON> operator[](std::string const & key) const {
  24. return this->value() ? &(*this->value())[key] : nullptr;
  25. }
  26. void assign(std::string const & key, Const const & frozen) const
  27. requires(not std::is_const_v<JSON>) {
  28. (*this)[key].assign(frozen);
  29. }
  30. };
  31. template <typename JSON> class JsonCppAdapter final : public detail::SimpleAdapter<JSON> {
  32. public:
  33. using JsonCppAdapter::SimpleAdapter::SimpleAdapter;
  34. Type type() const {
  35. switch (const_value().type()) {
  36. case Json::nullValue:
  37. return Type::Null;
  38. case Json::booleanValue:
  39. return Type::Boolean;
  40. case Json::realValue:
  41. if (Adapter::is_integer(as_number())) {
  42. return Type::Integer;
  43. }
  44. return Type::Number;
  45. case Json::stringValue:
  46. return Type::String;
  47. case Json::arrayValue:
  48. return Type::Array;
  49. case Json::objectValue:
  50. return Type::Object;
  51. case Json::intValue:
  52. case Json::uintValue:
  53. return Type::Integer;
  54. }
  55. }
  56. bool as_boolean() const { return const_value().asBool(); }
  57. int64_t as_integer() const { return const_value().asInt64(); }
  58. double as_number() const { return const_value().asDouble(); }
  59. std::string as_string() const { return const_value().asString(); }
  60. JsonCppObjectAdapter<JSON> as_object() const { return value(); }
  61. static std::string key(auto it) { return it.key().asString(); }
  62. using detail::SimpleAdapter<JSON>::assign;
  63. void assign(Adapter const & adapter) const requires(not std::is_const_v<JSON>) {
  64. switch (adapter.type()) {
  65. case Type::Null:
  66. *value() = Json::nullValue;
  67. return;
  68. case Type::Boolean:
  69. *value() = adapter.as_boolean();
  70. return;
  71. case Type::Integer:
  72. *value() = adapter.as_integer();
  73. return;
  74. case Type::Number:
  75. *value() = adapter.as_number();
  76. return;
  77. case Type::String:
  78. *value() = adapter.as_string();
  79. return;
  80. case Type::Array:
  81. adapter.apply_array([this, index = 0](Adapter const & elem) mutable {
  82. JsonCppAdapter((*value())[index]).assign(elem);
  83. ++index;
  84. return Status::Accept;
  85. });
  86. return;
  87. case Type::Object:
  88. adapter.apply_object([this](std::string const & key, Adapter const & elem) {
  89. JsonCppAdapter((*value())[key]).assign(elem);
  90. return Status::Accept;
  91. });
  92. return;
  93. }
  94. }
  95. public : using JsonCppAdapter::SimpleAdapter::value;
  96. using JsonCppAdapter::SimpleAdapter::const_value;
  97. };
  98. }