diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-02-23 00:39:06 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-02-23 00:39:06 +0000 |
commit | b59ba638083122456bfeab0ff1fc7e3f3af99423 (patch) | |
tree | 7874eb95e40d7bd1d8d8d2ecd513d98dfd936704 | |
parent | Implement loading asset, mesh and face definitions (diff) | |
download | ilt-b59ba638083122456bfeab0ff1fc7e3f3af99423.tar.bz2 ilt-b59ba638083122456bfeab0ff1fc7e3f3af99423.tar.xz ilt-b59ba638083122456bfeab0ff1fc7e3f3af99423.zip |
Support parsing string values in persistence read
-rw-r--r-- | lib/persistence.h | 47 | ||||
-rw-r--r-- | test/fixtures/json/conv.json | 4 | ||||
-rw-r--r-- | test/test-persistence.cpp | 8 |
3 files changed, 56 insertions, 3 deletions
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 <charconv> #include <functional> #include <glm/glm.hpp> #include <iosfwd> @@ -87,13 +88,53 @@ namespace Persistence { T & v; }; - template<typename T> struct SelectionT : public SelectionV<T> { + template<typename T> + concept Scalar = std::is_scalar_v<T>; + template<typename T> + concept NotScalar = (!Scalar<T>); + + template<Scalar T> struct SelectionT<T> : public SelectionV<T> { + using SelectionV<T>::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<T, bool>) { + 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<NotScalar T> struct SelectionT<T> : public SelectionV<T> { using SelectionV<T>::SelectionV; using Selection::setValue; - using P = std::conditional_t<std::is_scalar_v<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<std::unique_ptr<TestObject>>(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; |