summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-02-23 00:39:06 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2023-02-23 00:39:06 +0000
commitb59ba638083122456bfeab0ff1fc7e3f3af99423 (patch)
tree7874eb95e40d7bd1d8d8d2ecd513d98dfd936704
parentImplement loading asset, mesh and face definitions (diff)
downloadilt-b59ba638083122456bfeab0ff1fc7e3f3af99423.tar.bz2
ilt-b59ba638083122456bfeab0ff1fc7e3f3af99423.tar.xz
ilt-b59ba638083122456bfeab0ff1fc7e3f3af99423.zip
Support parsing string values in persistence read
-rw-r--r--lib/persistence.h47
-rw-r--r--test/fixtures/json/conv.json4
-rw-r--r--test/test-persistence.cpp8
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;