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) throw std::runtime_error(fmt::format("Invalid value, minimum={}, given={}", Value, value));
23 }
24};
25
26template <const auto& Value>
27struct Maximum final {
28 template <typename T>
29 static void Validate(T value) {
30 static_assert(std::is_arithmetic_v<T>);
31
32 if (value > Value) throw std::runtime_error(fmt::format("Invalid value, maximum={}, given={}", Value, value));
33 }
34};
35
36template <const auto& Value>
37struct ExclusiveMinimum final {
38 template <typename T>
39 static void Validate(T value) {
40 static_assert(std::is_arithmetic_v<T>);
41
42 if (value <= Value)
43 throw std::runtime_error(fmt::format("Invalid value, exclusive minimum={}, given={}", Value, value));
44 }
45};
46
47template <const auto& Value>
48struct ExclusiveMaximum final {
49 template <typename T>
50 static void Validate(T value) {
51 static_assert(std::is_arithmetic_v<T>);
52
53 if (value >= Value)
54 throw std::runtime_error(fmt::format("Invalid value, exclusive maximum={}, given={}", Value, value));
55 }
56};
57
58template <std::int64_t Value>
59struct MinItems final {
60 template <typename T>
61 static void Validate(const T& value) {
62 if (value.size() < Value) {
63 throw std::runtime_error(fmt::format("Too short array, minimum length={}, given={}", Value, value.size()));
64 }
65 }
66};
67
68template <std::int64_t Value>
69struct MaxItems final {
70 template <typename T>
71 static void Validate(const T& value) {
72 if (value.size() > Value) {
73 throw std::runtime_error(fmt::format("Too long array, maximum length={}, given={}", Value, value.size()));
74 }
75 }
76};
77
78template <std::int64_t Value>
79struct MinLength final {
80 static void Validate(std::string_view value) {
81 auto length = utils::text::utf8::GetCodePointsCount(value);
82 if (length < Value) {
83 throw std::runtime_error(fmt::format("Too short string, minimum length={}, given={}", Value, length));
84 }
85 }
86};
87
88template <std::int64_t Value>
89struct MaxLength final {
90 static void Validate(std::string_view value) {
91 auto length = utils::text::utf8::GetCodePointsCount(value);
92 if (length > Value) {
93 throw std::runtime_error(fmt::format("Too long string, maximum length={}, given={}", Value, length));
94 }
95 }
96};
97
98template <typename... Validators, typename Obj, typename Value>
99void Validate(const Obj& obj, const Value& value) {
100 try {
101 (Validators::Validate(obj), ...);
102 } catch (const std::exception& e) {
103 chaotic::ThrowForValue(e.what(), value);
104 }
105}
106
107} // namespace chaotic
108
109USERVER_NAMESPACE_END