Porytiles
Loading...
Searching...
No Matches
xcut_config_validators.hpp
Go to the documentation of this file.
1
44#pragma once
45
46#include <cstddef>
47#include <functional>
48#include <string>
49#include <vector>
50
54
55namespace porytiles {
56
68[[nodiscard]] inline ChainableResult<ConfigValue<std::size_t>>
70{
71 if (val == 0) {
72 std::vector<std::string> err_text{};
73 std::vector<std::vector<FormatParam>> params{};
74
75 err_text.emplace_back("'{}' must be greater than '{}'.");
76 params.emplace_back(std::vector{FormatParam{val.canonical_name(), Style::bold}, FormatParam{"0", Style::bold}});
77 err_text.emplace_back("");
78 params.emplace_back();
79
80 auto [format_text, format_params] = val.format_data();
81 err_text.append_range(format_text);
82 params.append_range(format_params);
83 return FormattableError{err_text, params};
84 }
85 return val;
86}
87
95[[nodiscard]] inline ChainableResult<ConfigValue<std::size_t>>
97{
98 if (val != 2 && val != 4) {
99 std::vector<std::string> err_text{};
100 std::vector<std::vector<FormatParam>> params{};
101
102 err_text.emplace_back("'{}' must be either '{}' or '{}'.");
103 params.emplace_back(
104 std::vector{
107 FormatParam{"4", Style::bold}});
108 err_text.emplace_back("");
109 params.emplace_back();
110
111 auto [format_text, format_params] = val.format_data();
112 err_text.append_range(format_text);
113 params.append_range(format_params);
114 return FormattableError{err_text, params};
115 }
116 return val;
117}
118
126[[nodiscard]] inline ChainableResult<ConfigValue<std::size_t>>
128{
129 if (val != 8 && val != 12) {
130 std::vector<std::string> err_text{};
131 std::vector<std::vector<FormatParam>> params{};
132
133 err_text.emplace_back("'{}' must be either '{}' or '{}'.");
134 params.emplace_back(
135 std::vector{
138 FormatParam{"12", Style::bold}});
139 err_text.emplace_back("");
140 params.emplace_back();
141
142 auto [format_text, format_params] = val.format_data();
143 err_text.append_range(format_text);
144 params.append_range(format_params);
145 return FormattableError{err_text, params};
146 }
147 return val;
148}
149
150namespace details {
151
175template <typename T, typename ConfigInterface, typename FetchFunc, typename Comparator>
177 const ConfigValue<T> &val,
178 const ConfigInterface &config,
179 ConfigScopeType type,
180 const std::string &scope,
181 const std::string &other_field_name,
182 FetchFunc fetch_other,
183 Comparator comp,
184 std::string_view error_message)
185{
186 auto other_result = fetch_other(config, type, scope);
187
188 // If fetching the other value failed, propagate that error
189 if (!other_result.has_value()) {
190 return other_result.error();
191 }
192
193 const auto &other_val = other_result.value();
194
195 // Perform the comparison
196 if (!comp(val.value(), other_val.value())) {
197 std::vector<std::string> err_text{};
198 std::vector<std::vector<FormatParam>> params{};
199
200 err_text.emplace_back("'{}' {} '{}'.");
201 params.emplace_back(
202 std::vector{
204 FormatParam{std::string{error_message}, Style::none},
205 FormatParam{other_field_name, Style::bold}});
206 err_text.emplace_back("");
207 params.emplace_back();
208
209 auto [format_text, format_params] = val.format_data();
210 err_text.append_range(format_text);
211 params.append_range(format_params);
212
213 err_text.emplace_back("");
214 params.emplace_back();
215 err_text.emplace_back("{}");
216 params.emplace_back(std::vector{FormatParam{"Comparison value:", Style::italic}});
217 err_text.emplace_back("");
218 params.emplace_back();
219
220 auto [other_format_text, other_format_params] = other_val.format_data();
221 err_text.append_range(other_format_text);
222 params.append_range(other_format_params);
223
224 return FormattableError{err_text, params};
225 }
226
227 return val;
228}
229
230} // namespace details
231
251template <typename T, typename ConfigInterface, typename FetchFunc>
253 const ConfigValue<T> &val,
254 const ConfigInterface &config,
255 ConfigScopeType type,
256 const std::string &scope,
257 const std::string &other_field_name,
258 FetchFunc fetch_other)
259{
261 val, config, type, scope, other_field_name, fetch_other, std::greater<>{}, "must be greater than");
262}
263
278template <typename T, typename ConfigInterface, typename FetchFunc>
280 const ConfigValue<T> &val,
281 const ConfigInterface &config,
282 ConfigScopeType type,
283 const std::string &scope,
284 const std::string &other_field_name,
285 FetchFunc fetch_other)
286{
288 val, config, type, scope, other_field_name, fetch_other, std::less<>{}, "must be less than");
289}
290
305template <typename T, typename ConfigInterface, typename FetchFunc>
307 const ConfigValue<T> &val,
308 const ConfigInterface &config,
309 ConfigScopeType type,
310 const std::string &scope,
311 const std::string &other_field_name,
312 FetchFunc fetch_other)
313{
315 val,
316 config,
317 type,
318 scope,
319 other_field_name,
320 fetch_other,
321 std::greater_equal<>{},
322 "must be greater than or equal to");
323}
324
339template <typename T, typename ConfigInterface, typename FetchFunc>
341 const ConfigValue<T> &val,
342 const ConfigInterface &config,
343 ConfigScopeType type,
344 const std::string &scope,
345 const std::string &other_field_name,
346 FetchFunc fetch_other)
347{
349 val, config, type, scope, other_field_name, fetch_other, std::less_equal<>{}, "must be less than or equal to");
350}
351
365template <typename T, typename ConfigInterface, typename FetchFunc>
367 const ConfigValue<T> &val,
368 const ConfigInterface &config,
369 const std::string &scope_param,
370 const std::string &other_field_name,
371 FetchFunc fetch_other)
372{
374 val, config, scope_param, other_field_name, fetch_other, std::equal_to<>{}, "must be equal to");
375}
376
390template <typename T, typename ConfigInterface, typename FetchFunc>
392 const ConfigValue<T> &val,
393 const ConfigInterface &config,
394 const std::string &scope_param,
395 const std::string &other_field_name,
396 FetchFunc fetch_other)
397{
399 val, config, scope_param, other_field_name, fetch_other, std::not_equal_to<>{}, "must not be equal to");
400}
401
402} // namespace porytiles
A result type that maintains a chainable sequence of errors for debugging and error reporting.
A container that wraps a configuration value with its name and source information.
std::pair< std::vector< std::string >, std::vector< std::vector< FormatParam > > > format_data() const
Generates formatted text data for displaying this configuration value.
const std::string & canonical_name() const
const T & value() const &
A text parameter with associated styling for formatted output.
General-purpose error implementation with formatted message support.
Definition error.hpp:63
static const Style italic
Italic text formatting.
static const Style none
No styling applied.
static const Style bold
Bold text formatting.
ChainableResult< ConfigValue< T > > compare_values(const ConfigValue< T > &val, const ConfigInterface &config, ConfigScopeType type, const std::string &scope, const std::string &other_field_name, FetchFunc fetch_other, Comparator comp, std::string_view error_message)
Generic comparison validator that compares the current value against another config value.
ChainableResult< ConfigValue< T > > compare_less_equal(const ConfigValue< T > &val, const ConfigInterface &config, ConfigScopeType type, const std::string &scope, const std::string &other_field_name, FetchFunc fetch_other)
Validates that the current value is less than or equal to another config value.
ChainableResult< ConfigValue< T > > compare_greater_than(const ConfigValue< T > &val, const ConfigInterface &config, ConfigScopeType type, const std::string &scope, const std::string &other_field_name, FetchFunc fetch_other)
Validates that the current value is greater than another config value.
ChainableResult< ConfigValue< std::size_t > > size_t_val_greater_than_zero(const ConfigValue< std::size_t > &val)
Validates that a size_t config value is greater than zero.
ChainableResult< ConfigValue< std::size_t > > size_t_val_eight_or_twelve(const ConfigValue< std::size_t > &val)
Validates that a size_t config value is either 8 or 12.
ChainableResult< ConfigValue< T > > compare_less_than(const ConfigValue< T > &val, const ConfigInterface &config, ConfigScopeType type, const std::string &scope, const std::string &other_field_name, FetchFunc fetch_other)
Validates that the current value is less than another config value.
ChainableResult< ConfigValue< T > > compare_equal(const ConfigValue< T > &val, const ConfigInterface &config, const std::string &scope_param, const std::string &other_field_name, FetchFunc fetch_other)
Validates that the current value is equal to another config value.
ChainableResult< ConfigValue< T > > compare_greater_equal(const ConfigValue< T > &val, const ConfigInterface &config, ConfigScopeType type, const std::string &scope, const std::string &other_field_name, FetchFunc fetch_other)
Validates that the current value is greater than or equal to another config value.
ChainableResult< ConfigValue< T > > compare_not_equal(const ConfigValue< T > &val, const ConfigInterface &config, const std::string &scope_param, const std::string &other_field_name, FetchFunc fetch_other)
Validates that the current value is not equal to another config value.
ConfigScopeType
Specifies the scope type for configuration value lookups.
ChainableResult< ConfigValue< std::size_t > > size_t_val_two_or_four(const ConfigValue< std::size_t > &val)
Validates that a size_t config value is either 2 or 4.