// // json_binder_custom.t.h // json // // Created by Sam Jaffe on 9/12/17. // #include "json/json_binder.hpp" #include #include #include using namespace json::binder; using namespace json::parser; class precision_binder : public binder_impl { public: precision_binder(int d) : digits(d), trunc(std::pow(10, d)) {} virtual ~precision_binder() = default; binder_impl * clone() const override { return new precision_binder{*this}; } void parse(double & value, char const *& str, options) const override { std::sscanf(str, "%lf", &value); value = static_cast(value * trunc) / trunc; json::parse_discard_token(str); // Advance to the boundary } void write(double const & value, std::ostream & out) const override { out << std::fixed << std::setprecision(digits) << value; } private: int digits; double trunc; }; struct CustomObject { double A; // four_digits double B; // two_digits double C; }; bool operator==(CustomObject const & lhs, CustomObject const & rhs) { return lhs.A == rhs.A && lhs.B == rhs.B && lhs.C == rhs.C; } class JsonBinderCustomTest : public ::testing::Test { protected: static object_binder & GetBinder() { static object_binder val = object_binder()( "A", &CustomObject::A, precision_binder(4))( "B", &CustomObject::B, precision_binder(2))("C", &CustomObject::C); return val; } }; TEST_F(JsonBinderCustomTest, CustomBindersWillParse) { char data[] = "{\"A\":1.00008, \"B\":1.0, \"C\":1.523211102}"; CustomObject out{0.0, 0.0, 0.0}; CustomObject const expected{1.0, 1.0, 1.523211102}; EXPECT_NO_THROW(parse(json::binder::bind(out, GetBinder()), data)); EXPECT_THAT(out, expected); }