From b59ba638083122456bfeab0ff1fc7e3f3af99423 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 23 Feb 2023 00:39:06 +0000 Subject: Support parsing string values in persistence read --- lib/persistence.h | 47 +++++++++++++++++++++++++++++++++++++++++--- test/fixtures/json/conv.json | 4 ++++ test/test-persistence.cpp | 8 ++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/json/conv.json diff --git a/lib/persistence.h b/lib/persistence.h index 0fc0200..bfd27f0 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -87,13 +88,53 @@ namespace Persistence { T & v; }; - template struct SelectionT : public SelectionV { + template + concept Scalar = std::is_scalar_v; + template + concept NotScalar = (!Scalar); + + template struct SelectionT : public SelectionV { + using SelectionV::SelectionV; + using Selection::setValue; + + void + setValue(T evalue) override + { + std::swap(this->v, evalue); + } + + void + setValue(std::string && evalue) override + { + if constexpr (std::same_as) { + using namespace std::literals; + if (!(this->v = evalue == "true"sv)) { + if (evalue != "false"sv) { + throw std::runtime_error("Value conversion failure"); + } + } + } + else { + if (auto res = std::from_chars(evalue.c_str(), evalue.c_str() + evalue.length(), this->v).ec; + res != std::errc {}) { + throw std::runtime_error("Value conversion failure"); + } + } + } + + void + write(const Writer & out) const override + { + out.pushValue(this->v); + } + }; + + template struct SelectionT : public SelectionV { using SelectionV::SelectionV; using Selection::setValue; - using P = std::conditional_t, T, T &&>; void - setValue(P evalue) override + setValue(T && evalue) override { std::swap(this->v, evalue); } diff --git a/test/fixtures/json/conv.json b/test/fixtures/json/conv.json new file mode 100644 index 0000000..1b690d5 --- /dev/null +++ b/test/fixtures/json/conv.json @@ -0,0 +1,4 @@ +{ + "bl": "true", + "flt": "3.14" +} diff --git a/test/test-persistence.cpp b/test/test-persistence.cpp index faa0d19..6bee010 100644 --- a/test/test-persistence.cpp +++ b/test/test-persistence.cpp @@ -208,6 +208,14 @@ BOOST_FIXTURE_TEST_CASE(load_vector_ptr, JPP) BOOST_CHECK(to->vptr.at(3)->str.empty()); } +BOOST_FIXTURE_TEST_CASE(test_conversion, JPP) +{ + auto to = load_json>(FIXTURESDIR "json/conv.json"); + BOOST_REQUIRE(to); + BOOST_CHECK_EQUAL(to->bl, true); + BOOST_CHECK_EQUAL(to->flt, 3.14F); +} + struct SharedTestObject : public Persistence::Persistable { SharedTestObject() = default; -- cgit v1.2.3