userver: userver/chaotic/validators.hpp Source File
Loading...
Searching...
No Matches
validators.hpp
1#pragma once
2
3#include <cstdint>
4#include <stdexcept>
5#include <string>
6
7#include <fmt/format.h>
8
9#include <userver/chaotic/exception.hpp>
10#include <userver/utils/text_light.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace chaotic {
15
16template <const auto& Value>
17struct Minimum final {
18 template <typename T>
19 static void Validate(T value) {
20 static_assert(std::is_arithmetic_v<T>);
21
22 if (value < Value)
23 throw std::runtime_error(
24 fmt::format("Invalid value, minimum={}, given={}", Value, value));
25 }
26};
27
28template <const auto& Value>
29struct Maximum final {
30 template <typename T>
31 static void Validate(T value) {
32 static_assert(std::is_arithmetic_v<T>);
33
34 if (value > Value)
35 throw std::runtime_error(
36 fmt::format("Invalid value, maximum={}, given={}", Value, value));
37 }
38};
39
40template <const auto& Value>
41struct ExclusiveMinimum final {
42 template <typename T>
43 static void Validate(T value) {
44 static_assert(std::is_arithmetic_v<T>);
45
46 if (value <= Value)
47 throw std::runtime_error(fmt::format(
48 "Invalid value, exclusive minimum={}, given={}", Value, value));
49 }
50};
51
52template <const auto& Value>
53struct ExclusiveMaximum final {
54 template <typename T>
55 static void Validate(T value) {
56 static_assert(std::is_arithmetic_v<T>);
57
58 if (value >= Value)
59 throw std::runtime_error(fmt::format(
60 "Invalid value, exclusive maximum={}, given={}", Value, value));
61 }
62};
63
64template <std::int64_t Value>
65struct MinItems final {
66 template <typename T>
67 static void Validate(const T& value) {
68 if (value.size() < Value) {
69 throw std::runtime_error(fmt::format(
70 "Too short array, minimum length={}, given={}", Value, value.size()));
71 }
72 }
73};
74
75template <std::int64_t Value>
76struct MaxItems final {
77 template <typename T>
78 static void Validate(const T& value) {
79 if (value.size() > Value) {
80 throw std::runtime_error(fmt::format(
81 "Too long array, maximum length={}, given={}", Value, value.size()));
82 }
83 }
84};
85
86template <std::int64_t Value>
87struct MinLength final {
88 static void Validate(std::string_view value) {
89 auto length = utils::text::utf8::GetCodePointsCount(value);
90 if (length < Value) {
91 throw std::runtime_error(fmt::format(
92 "Too short string, minimum length={}, given={}", Value, length));
93 }
94 }
95};
96
97template <std::int64_t Value>
98struct MaxLength final {
99 static void Validate(std::string_view value) {
100 auto length = utils::text::utf8::GetCodePointsCount(value);
101 if (length > Value) {
102 throw std::runtime_error(fmt::format(
103 "Too long string, maximum length={}, given={}", Value, length));
104 }
105 }
106};
107
108template <typename... Validators, typename Obj, typename Value>
109void Validate(const Obj& obj, const Value& value) {
110 try {
111 (Validators::Validate(obj), ...);
112 } catch (const std::exception& e) {
113 chaotic::ThrowForValue(e.what(), value);
114 }
115}
116
117} // namespace chaotic
118
119USERVER_NAMESPACE_END