json_binder.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. //
  2. // json_binder.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 1/31/16.
  6. // Copyright © 2016 Sam Jaffe. All rights reserved.
  7. //
  8. #ifndef json_binder_h
  9. #define json_binder_h
  10. #pragma once
  11. #include "json_common.hpp"
  12. #include <map>
  13. #include <string>
  14. #include <sstream>
  15. #include <vector>
  16. namespace json {
  17. namespace binder {
  18. template <typename T>
  19. class binder_impl {
  20. public:
  21. virtual binder_impl<T>* clone() const = 0;
  22. virtual ~binder_impl() {}
  23. virtual void parse(T&, char const*&, parser::options) const = 0;
  24. virtual void write(T const&, std::ostream &) const = 0;
  25. };
  26. template <typename T>
  27. class binder {
  28. public:
  29. binder() : impl(nullptr) {}
  30. binder(binder const& other) : impl(other.impl->clone()) {}
  31. binder(binder_impl<T> const* p) : impl(p) {}
  32. binder(binder_impl<T> const& r) : impl(r.clone()) {}
  33. ~binder() { delete impl; }
  34. void parse(T& object, char const*& data, parser::options opts) const {
  35. if (!impl) return; // error?
  36. impl->parse(object, data, opts);
  37. }
  38. void write(T const& object, std::ostream & data) const {
  39. if (!impl) return; // error?
  40. impl->write(object, data);
  41. }
  42. private:
  43. binder_impl<T> const* impl;
  44. };
  45. template <typename T, typename S = T>
  46. class visitor {
  47. public:
  48. visitor(S& o, binder_impl<T>& b) : obj(o), b(b) {}
  49. void parse(char const* data, parser::options opts) {
  50. b.parse(obj, data, opts);
  51. if ( json::helper::get_next_element(data) && opts & parser::disable_concatenated_json_bodies ) {
  52. throw malformed_json_exception{"Config set to require json input be terminated"};
  53. }
  54. }
  55. void write(std::ostream & data) const {
  56. b.write(obj, data);
  57. }
  58. private:
  59. S& obj;
  60. binder_impl<T>& b;
  61. };
  62. template <typename T, typename S>
  63. visitor<T, S> bind(S& object, binder_impl<T>& b) {
  64. return visitor<T, S>{object, b};
  65. }
  66. }
  67. namespace parser {
  68. template <typename T>
  69. void parse(binder::visitor<T>& visitor, char const* data, options opts = allow_all) {
  70. visitor.parse(data, opts);
  71. }
  72. template <typename T, typename S>
  73. void write(binder::visitor<T, S> const & visitor, std::ostream & out) {
  74. visitor.write(out);
  75. }
  76. template <typename T, typename S>
  77. void write(binder::visitor<T, S> const & visitor, std::string & data) {
  78. std::stringstream ss;
  79. visitor.write(ss);
  80. data = ss.str();
  81. }
  82. }
  83. }
  84. #include "json/json_binder_parser.hpp"
  85. #include "json/json_direct_binder.hpp"
  86. #include "json/json_tuple_binder.hpp"
  87. #include "json/json_object_binder.hpp"
  88. #include "json/json_direct_get_binder.hpp"
  89. #include "json/json_direct_map_binder.hpp"
  90. #include "json/json_direct_scalar_binder.hpp"
  91. #include "json/json_direct_vector_binder.hpp"
  92. #endif /* json_binder_h */