json_tuple_binder.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. //
  2. // json_tuple_binder.hpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/23/16.
  6. //
  7. #pragma once
  8. #include "json_binder.hpp"
  9. #include "json_direct_binder.hpp"
  10. #include <vector>
  11. namespace json { namespace binder {
  12. template <typename T>
  13. class tuple_binder : public binder_impl<T> {
  14. public:
  15. virtual binder_impl<T>* clone() const override {
  16. return new tuple_binder(*this);
  17. }
  18. tuple_binder& operator()(binder<T> const&b) {
  19. members.push_back(b);
  20. return *this;
  21. }
  22. virtual void parse(T& object, char const*& data,
  23. parser::options opts) const override {
  24. const char ch = json::helper::get_next_element(data);
  25. if (ch == '[') {
  26. parse_tuple(object, ++data, opts);
  27. } else {
  28. throw not_an_array_exception(object);
  29. }
  30. }
  31. virtual void write(T const& val, std::ostream & data) const override {
  32. data << '[';
  33. typename std::vector<binder<T>>::const_iterator it = members.begin(),
  34. end = members.end();
  35. if (it != end) {
  36. it->write(val, data);
  37. for (++it; it != end; ++it) {
  38. data << ',';
  39. it->write(val, data);
  40. }
  41. }
  42. data << ']';
  43. }
  44. void parse_tuple(T& object, char const*& data,
  45. parser::options opts) const {
  46. auto it = members.begin();
  47. while (*data && *data != ']' && it != members.end()) {
  48. it->parse(object, data, opts);
  49. json::helper::advance_to_boundary(']', data);
  50. ++it;
  51. }
  52. if (it != members.end()) {
  53. throw json::malformed_json_exception{
  54. "Failed to parse every member of tuple"
  55. };
  56. }
  57. if (*data != ']') throw json::malformed_json_exception{
  58. "Parsed every tuple element, but did not reach end"
  59. };
  60. else if (*data) ++data;
  61. else throw unterminated_json_array();
  62. }
  63. template <typename E>
  64. tuple_binder& operator()(E T::*p) {
  65. return operator()(binder<T>(new direct_binder<T, E>(p)));
  66. }
  67. private:
  68. std::vector<binder<T>> members;
  69. };
  70. } }