Skip to content

Commit

Permalink
Fix try_json_decode throwing exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-jung committed Oct 8, 2022
1 parent 2e6bcf2 commit 28d844b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
14 changes: 11 additions & 3 deletions include/tsmp/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ struct from_json_t<T, ErrorHandler> {
if(!json.is_string()) {
return ErrorHandler<T>{}(fmt::format("{} is not a string", json.dump()));
}
return enum_from_string<T>(static_cast<std::string>(json));
try { // TODO remove try/catch block
return enum_from_string<T>(static_cast<std::string>(json));
} catch(...) {
return ErrorHandler<T>{}("String not in enumeration");
}
}
};

Expand Down Expand Up @@ -212,7 +216,11 @@ struct from_json_t<immutable_t<value>, ErrorHandler> {
using value_type = typename ErrorHandler<immutable_t<value>>::value_type;
[[nodiscard]] value_type operator()(const nlohmann::json& json) {
using capture_type = typename immutable_t<value>::value_type;
return { from_json_t<std::remove_const_t<capture_type>, ErrorHandler>{}(json) };
try { // TODO remove try/catch block
return { from_json_t<std::remove_const_t<capture_type>, ErrorHandler>{}(json) };
} catch(...) {
return ErrorHandler<immutable_t<value>>{}("Value missmatch");
}
}
};

Expand All @@ -238,7 +246,7 @@ struct from_json_t<std::variant<Args...>, ErrorHandler> {
[[nodiscard]] static std::optional<value_type> try_decode(const nlohmann::json& json) noexcept {
const auto result = from_json_t<T, nullopt_handler_t>{}(json);
if(result) {
return value_type{ result.value() };
return value_type{ std::move(result.value()) };
} else {
return std::nullopt;
}
Expand Down
30 changes: 30 additions & 0 deletions test/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "tsmp/string_literal.hpp"
#include <catch2/catch_all.hpp>
#include <catch2/catch_test_macros.hpp>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <deque>
Expand Down Expand Up @@ -38,6 +39,9 @@ TEST_CASE("enum json test", "[core][unit]") {

REQUIRE(tsmp::to_json(tsmp::immutable_t<enum_t::value1>()) == "\"value1\"");
REQUIRE(tsmp::from_json<tsmp::immutable_t<enum_t::value1>>("\"value1\"") == enum_t::value1);

REQUIRE_THROWS(tsmp::from_json<enum_t>("\"invalid\""));
REQUIRE(tsmp::try_from_json<enum_t>("\"invalid\"") == std::nullopt);
}

TEST_CASE("string json test", "[core][unit]") {
Expand Down Expand Up @@ -163,4 +167,30 @@ TEST_CASE("validator json test", "[core][unit]") {

REQUIRE(tsmp::from_json<std::uint32_t>("42.0", is_fourtytwo) == 42);
REQUIRE(tsmp::try_from_json<std::uint32_t>("42", not_fourtytwo) == std::nullopt);
}

TEST_CASE("complex variant json test", "[core][unit]") {
enum class enum_t {
foo,
bar
};
using small_t = std::variant<tsmp::immutable_t<enum_t::foo>, tsmp::immutable_t<enum_t::bar>>;
REQUIRE_NOTHROW(tsmp::from_json<small_t>("\"foo\""));
REQUIRE_NOTHROW(tsmp::from_json<small_t>("\"bar\""));

struct foo_t {
tsmp::immutable_t<enum_t::foo> type;
};

struct bar_t {
tsmp::immutable_t<enum_t::bar> type;
};

using adapter = tsmp::enum_value_adapter<enum_t>;

using variant = std::variant<foo_t, bar_t>;
REQUIRE(tsmp::to_json(variant(foo_t{})) == "{\"type\":\"foo\"}");
REQUIRE(tsmp::to_json(variant(bar_t{})) == "{\"type\":\"bar\"}");
REQUIRE_NOTHROW(std::get<foo_t>(tsmp::from_json<variant>("{\"type\":\"foo\"}")));
REQUIRE_NOTHROW(std::get<bar_t>(tsmp::from_json<variant>("{\"type\":\"bar\"}")));
}

0 comments on commit 28d844b

Please sign in to comment.