From ac0dcd4210fdcec71c7fd998bde55a9174545c46 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Thu, 7 Aug 2025 22:49:33 +0200 Subject: [PATCH 1/2] Use stringstreams for the error messages in the validators; fixes #475 --- include/rfl/comparisons.hpp | 43 +++++++++-------- tests/json/test_validation_with_fields.cpp | 54 ++++++++++++++++++++++ 2 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 tests/json/test_validation_with_fields.cpp diff --git a/include/rfl/comparisons.hpp b/include/rfl/comparisons.hpp index f4a73907..2dfb4674 100644 --- a/include/rfl/comparisons.hpp +++ b/include/rfl/comparisons.hpp @@ -1,6 +1,7 @@ #ifndef RFL_COMPARISONS_HPP_ #define RFL_COMPARISONS_HPP_ +#include #include #include "Result.hpp" @@ -14,9 +15,10 @@ struct EqualTo { static Result validate(T _value) noexcept { constexpr auto threshold = static_cast(_threshold); if (_value != threshold) { - return error("Value expected to be equal to " + - std::to_string(threshold) + ", but got " + - std::to_string(_value) + "."); + std::stringstream stream; + stream << "Value expected to be equal to " << threshold << ", but got " + << _value << "."; + return error(stream.str()); } return _value; } @@ -38,9 +40,10 @@ struct Minimum { static Result validate(T _value) noexcept { constexpr auto threshold = static_cast(_threshold); if (_value < threshold) { - return error("Value expected to be greater than or equal to " + - std::to_string(threshold) + ", but got " + - std::to_string(_value) + "."); + std::stringstream stream; + stream << "Value expected to be greater than or equal to " << threshold + << ", but got " << _value << "."; + return error(stream.str()); } return _value; } @@ -62,9 +65,10 @@ struct ExclusiveMinimum { static Result validate(T _value) noexcept { constexpr auto threshold = static_cast(_threshold); if (_value <= threshold) { - return error("Value expected to be greater than " + - std::to_string(threshold) + ", but got " + - std::to_string(_value) + "."); + std::stringstream stream; + stream << "Value expected to be greater than " << threshold + << ", but got " << _value << "."; + return error(stream.str()); } return _value; } @@ -86,9 +90,10 @@ struct Maximum { static Result validate(T _value) noexcept { constexpr auto threshold = static_cast(_threshold); if (_value > threshold) { - return error("Value expected to be less than or equal to " + - std::to_string(threshold) + ", but got " + - std::to_string(_value) + "."); + std::stringstream stream; + stream << "Value expected to be less than or equal to " << threshold + << ", but got " << _value << "."; + return error(stream.str()); } return _value; } @@ -110,9 +115,10 @@ struct ExclusiveMaximum { static Result validate(T _value) noexcept { constexpr auto threshold = static_cast(_threshold); if (_value >= threshold) { - return error("Value expected to be less than " + - std::to_string(threshold) + ", but got " + - std::to_string(_value) + "."); + std::stringstream stream; + stream << "Value expected to be less than " << threshold << ", but got " + << _value << "."; + return error(stream.str()); } return _value; } @@ -134,9 +140,10 @@ struct NotEqualTo { static Result validate(T _value) noexcept { constexpr auto threshold = static_cast(_threshold); if (_value == threshold) { - return error("Value expected to not be equal to " + - std::to_string(threshold) + ", but got " + - std::to_string(_value) + "."); + std::stringstream stream; + stream << "Value expected not to be equal to " << threshold + << ", but got " << _value << "."; + return error(stream.str()); } return _value; } diff --git a/tests/json/test_validation_with_fields.cpp b/tests/json/test_validation_with_fields.cpp new file mode 100644 index 00000000..83fc8fe3 --- /dev/null +++ b/tests/json/test_validation_with_fields.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include "write_and_read.hpp" + +namespace test_validation_with_fields { + +using SimpleNameValidator = rfl::Validator< + std::string, + rfl::AllOf>, + rfl::Size>, rfl::Size>>; + +struct TagConfig { + SimpleNameValidator Name; + int32_t Length; + bool WriteEnabled; +}; + +struct ThreadConfig { + rfl::Field<"type", SimpleNameValidator> Type; + rfl::Field<"Name", SimpleNameValidator> Name; + rfl::Field<"ReadTags", std::vector> ReadTags; + rfl::Field<"WriteTags", std::vector> WriteTags; + rfl::Field<"ThreadPriority", int32_t> ThreadPriority; + rfl::Field<"DecimationFactor", int32_t> DecimationFactor; + rfl::Field<"TimingOffset", int32_t> TimingOffset; +}; + +TEST(json, test_validation_with_fields) { + const auto read_tag1 = + TagConfig{.Name = "READ_TAG_1", .Length = 5, .WriteEnabled = false}; + + const auto write_tag1 = + TagConfig{.Name = "WRITE_TAG_1", .Length = 10, .WriteEnabled = true}; + + const auto test_thread_config = + ThreadConfig{.Type = "BasicThread", + .Name = "TEST_1", + .ReadTags = std::vector({read_tag1}), + .WriteTags = std::vector({write_tag1}), + .ThreadPriority = -1, + .DecimationFactor = 10, + .TimingOffset = 0}; + + const auto json_string = rfl::json::write(test_thread_config); + + write_and_read( + test_thread_config, + R"({"type":"BasicThread","Name":"TEST_1","ReadTags":[{"Name":"READ_TAG_1","Length":5,"WriteEnabled":false}],"WriteTags":[{"Name":"WRITE_TAG_1","Length":10,"WriteEnabled":true}],"ThreadPriority":-1,"DecimationFactor":10,"TimingOffset":0})"); +} + +} // namespace test_validation_with_fields From aa756962623e1c795fc79dd6394f8e83fc8dab0f Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Thu, 7 Aug 2025 23:03:40 +0200 Subject: [PATCH 2/2] Removed unused json_string --- tests/json/test_validation_with_fields.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/json/test_validation_with_fields.cpp b/tests/json/test_validation_with_fields.cpp index 83fc8fe3..380dc9c5 100644 --- a/tests/json/test_validation_with_fields.cpp +++ b/tests/json/test_validation_with_fields.cpp @@ -44,8 +44,6 @@ TEST(json, test_validation_with_fields) { .DecimationFactor = 10, .TimingOffset = 0}; - const auto json_string = rfl::json::write(test_thread_config); - write_and_read( test_thread_config, R"({"type":"BasicThread","Name":"TEST_1","ReadTags":[{"Name":"READ_TAG_1","Length":5,"WriteEnabled":false}],"WriteTags":[{"Name":"WRITE_TAG_1","Length":10,"WriteEnabled":true}],"ThreadPriority":-1,"DecimationFactor":10,"TimingOffset":0})");