json_tuple_binder.hpp 2.1 KB

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