json_binder_custom.t.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //
  2. // json_binder_custom.t.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 9/12/17.
  6. //
  7. #pragma once
  8. #include <cxxtest/TestSuite.h>
  9. #include "json/json_binder.hpp"
  10. #include <iomanip>
  11. using namespace json::binder;
  12. using namespace json::parser;
  13. class precision_binder : public binder_impl<double> {
  14. public:
  15. precision_binder(int d) : digits(d), trunc(std::pow(10, d)) {}
  16. virtual ~precision_binder() = default;
  17. binder_impl<double> * clone() const override {
  18. return new precision_binder{*this};
  19. }
  20. void parse(double & value, char const * & str, options) const override {
  21. std::sscanf(str, "%lf", &value);
  22. value = static_cast<long long>(value * trunc) / trunc;
  23. json::parse_discard_token(str); // Advance to the boundary
  24. }
  25. void write(double const & value, std::ostream & out) const override {
  26. out << std::fixed << std::setprecision(digits) << value;
  27. }
  28. private:
  29. int digits;
  30. double trunc;
  31. };
  32. class json_binder_custom_TestSuite : public CxxTest::TestSuite {
  33. public:
  34. struct TestObject {
  35. double A; // four_digits
  36. double B; // two_digits
  37. double C;
  38. bool operator==(TestObject const & other) const {
  39. return A == other.A && B == other.B && C == other.C;
  40. }
  41. };
  42. static object_binder<TestObject> GetImpl() {
  43. return object_binder<TestObject>()
  44. ("A", &TestObject::A, precision_binder(4))
  45. ("B", &TestObject::B, precision_binder(2))
  46. ("C", &TestObject::C);
  47. }
  48. static object_binder<TestObject> & Get() {
  49. static object_binder<TestObject> val = GetImpl();
  50. return val;
  51. }
  52. void test_() {
  53. char data[] = "{\"A\":1.00008, \"B\":1.0, \"C\":1.523211102}";
  54. TestObject out{0.0, 0.0, 0.0};
  55. TestObject const expected{1.0, 1.0, 1.523211102};
  56. TS_ASSERT_THROWS_NOTHING(parse(json::binder::bind(out, Get()), data));
  57. TS_ASSERT_EQUALS(out, expected);
  58. }
  59. };