11#pragma once
22
33#include < cstdint>
4- #include < stdexcept>
54#include < string>
65
76#include < userver/chaotic/exception.hpp>
@@ -15,99 +14,100 @@ namespace chaotic {
1514
1615template <const auto & Value>
1716struct Minimum final {
18- template <typename T>
19- static void Validate (T value) {
17+ template <typename T, typename ErrorReporter >
18+ static void Validate (T value, ErrorReporter report_error ) {
2019 static_assert (std::is_arithmetic_v<T>);
2120
2221 if (value < Value) {
23- throw std::runtime_error (fmt::format (" Invalid value, minimum={}, given={}" , Value, value));
22+ report_error (fmt::format (" Invalid value, minimum={}, given={}" , Value, value));
2423 }
2524 }
2625};
2726
2827template <const auto & Value>
2928struct Maximum final {
30- template <typename T>
31- static void Validate (T value) {
29+ template <typename T, typename ErrorReporter >
30+ static void Validate (T value, ErrorReporter report_error ) {
3231 static_assert (std::is_arithmetic_v<T>);
3332
3433 if (value > Value) {
35- throw std::runtime_error (fmt::format (" Invalid value, maximum={}, given={}" , Value, value));
34+ report_error (fmt::format (" Invalid value, maximum={}, given={}" , Value, value));
3635 }
3736 }
3837};
3938
4039template <const auto & Value>
4140struct ExclusiveMinimum final {
42- template <typename T>
43- static void Validate (T value) {
41+ template <typename T, typename ErrorReporter >
42+ static void Validate (T value, ErrorReporter report_error ) {
4443 static_assert (std::is_arithmetic_v<T>);
4544
4645 if (value <= Value) {
47- throw std::runtime_error (fmt::format (" Invalid value, exclusive minimum={}, given={}" , Value, value));
46+ report_error (fmt::format (" Invalid value, exclusive minimum={}, given={}" , Value, value));
4847 }
4948 }
5049};
5150
5251template <const auto & Value>
5352struct ExclusiveMaximum final {
54- template <typename T>
55- static void Validate (T value) {
53+ template <typename T, typename ErrorReporter >
54+ static void Validate (T value, ErrorReporter report_error ) {
5655 static_assert (std::is_arithmetic_v<T>);
5756
5857 if (value >= Value) {
59- throw std::runtime_error (fmt::format (" Invalid value, exclusive maximum={}, given={}" , Value, value));
58+ report_error (fmt::format (" Invalid value, exclusive maximum={}, given={}" , Value, value));
6059 }
6160 }
6261};
6362
6463template <std::int64_t Value>
6564struct MinItems final {
66- template <typename T>
67- static void Validate (const T& value) {
65+ template <typename T, typename ErrorReporter >
66+ static void Validate (const T& value, ErrorReporter report_error ) {
6867 if (value.size () < Value) {
69- throw std::runtime_error (fmt::format (" Too short array, minimum length={}, given={}" , Value, value.size ()));
68+ report_error (fmt::format (" Too short array, minimum length={}, given={}" , Value, value.size ()));
7069 }
7170 }
7271};
7372
7473template <std::int64_t Value>
7574struct MaxItems final {
76- template <typename T>
77- static void Validate (const T& value) {
75+ template <typename T, typename ErrorReporter >
76+ static void Validate (const T& value, ErrorReporter report_error ) {
7877 if (value.size () > Value) {
79- throw std::runtime_error (fmt::format (" Too long array, maximum length={}, given={}" , Value, value.size ()));
78+ report_error (fmt::format (" Too long array, maximum length={}, given={}" , Value, value.size ()));
8079 }
8180 }
8281};
8382
8483template <std::int64_t Value>
8584struct MinLength final {
86- static void Validate (std::string_view value) {
87- auto length = utils::text::utf8::GetCodePointsCount (value);
85+ template <typename ErrorReporter>
86+ static void Validate (std::string_view value, ErrorReporter report_error) {
87+ const auto length = utils::text::utf8::GetCodePointsCount (value);
8888 if (length < Value) {
89- throw std::runtime_error (fmt::format (" Too short string, minimum length={}, given={}" , Value, length));
89+ report_error (fmt::format (" Too short string, minimum length={}, given={}" , Value, length));
9090 }
9191 }
9292};
9393
9494template <std::int64_t Value>
9595struct MaxLength final {
96- static void Validate (std::string_view value) {
97- auto length = utils::text::utf8::GetCodePointsCount (value);
96+ template <typename ErrorReporter>
97+ static void Validate (std::string_view value, ErrorReporter report_error) {
98+ const auto length = utils::text::utf8::GetCodePointsCount (value);
9899 if (length > Value) {
99- throw std::runtime_error (fmt::format (" Too long string, maximum length={}, given={}" , Value, length));
100+ report_error (fmt::format (" Too long string, maximum length={}, given={}" , Value, length));
100101 }
101102 }
102103};
103104
104105template <typename ... Validators, typename Obj, typename Value>
105106void Validate (const Obj& obj, const Value& value) {
106- try {
107- (Validators::Validate (obj), ...);
108- } catch (const std::exception& e) {
109- chaotic::ThrowForValue (e.what (), value);
110- }
107+ [[maybe_unused]] const auto error_reporter = [&value](std::string_view error) {
108+ chaotic::ThrowForValue (error, value);
109+ };
110+ (Validators::Validate (obj, error_reporter), ...);
111111}
112112
113113} // namespace chaotic
0 commit comments