Porytiles
Loading...
Searching...
No Matches
xcut_config_validators.hpp
Go to the documentation of this file.
1
41
42#pragma once
43
44#include <cstddef>
45#include <functional>
46#include <optional>
47#include <string>
48#include <vector>
49
53
54namespace porytiles {
55
65[[nodiscard]] inline ChainableResult<ConfigValue<std::size_t>>
67{
68 if (val == 0) {
69 std::vector<std::string> err_text{};
70 std::vector<std::vector<FormatParam>> params{};
71
72 err_text.emplace_back("'{}' must be greater than '{}'.");
73 params.emplace_back(std::vector{FormatParam{val.canonical_name(), Style::bold}, FormatParam{"0", Style::bold}});
74 err_text.emplace_back("");
75 params.emplace_back();
76
77 auto [format_text, format_params] = val.format_data();
78 err_text.append_range(format_text);
79 params.append_range(format_params);
80 return FormattableError{err_text, params};
81 }
82 return val;
83}
84
90[[nodiscard]] inline ChainableResult<ConfigValue<std::size_t>>
92{
93 if (val != 8 && val != 12) {
94 std::vector<std::string> err_text{};
95 std::vector<std::vector<FormatParam>> params{};
96
97 err_text.emplace_back("'{}' must be either '{}' or '{}'.");
98 params.emplace_back(
99 std::vector{
102 FormatParam{"12", Style::bold}});
103 err_text.emplace_back("");
104 params.emplace_back();
105
106 auto [format_text, format_params] = val.format_data();
107 err_text.append_range(format_text);
108 params.append_range(format_params);
109 return FormattableError{err_text, params};
110 }
111 return val;
112}
113
119[[nodiscard]] inline ChainableResult<ConfigValue<std::size_t>>
121{
122 if (val != 1 && val != 2 && val != 4) {
123 std::vector<std::string> err_text{};
124 std::vector<std::vector<FormatParam>> params{};
125
126 err_text.emplace_back("'{}' must be '{}', '{}', or '{}'.");
127 params.emplace_back(
128 std::vector{
132 FormatParam{"4", Style::bold}});
133 err_text.emplace_back("");
134 params.emplace_back();
135
136 auto [format_text, format_params] = val.format_data();
137 err_text.append_range(format_text);
138 params.append_range(format_params);
139 return FormattableError{err_text, params};
140 }
141 return val;
142}
143
154[[nodiscard]] inline ChainableResult<ConfigValue<std::optional<std::size_t>>>
155optional_size_t_val_one_two_or_four(const ConfigValue<std::optional<std::size_t>> &val)
156{
157 if (!val.value().has_value()) {
158 return val;
159 }
160 const ConfigValue<std::size_t> present{
161 val.value().value(), val.canonical_name(), val.source_key(), val.source(), val.source_details()};
162 auto checked = size_t_val_one_two_or_four(present);
163 if (!checked.has_value()) {
164 return checked.error();
165 }
166 return val;
167}
168
169namespace details {
170
192template <typename T, typename ConfigInterface, typename FetchFunc, typename Comparator>
194 const ConfigValue<T> &val,
195 const ConfigInterface &config,
196 ConfigScopeType type,
197 const std::string &scope,
198 const std::string &other_field_name,
199 FetchFunc fetch_other,
200 Comparator comp,
201 std::string_view error_message)
202{
203 auto other_result = fetch_other(config, type, scope);
204
205 // If fetching the other value failed, propagate that error
206 if (!other_result.has_value()) {
207 return other_result.error();
208 }
209
210 const auto &other_val = other_result.value();
211
212 // Perform the comparison
213 if (!comp(val.value(), other_val.value())) {
214 std::vector<std::string> err_text{};
215 std::vector<std::vector<FormatParam>> params{};
216
217 err_text.emplace_back("'{}' {} '{}'.");
218 params.emplace_back(
219 std::vector{
221 FormatParam{std::string{error_message}, Style::none},
222 FormatParam{other_field_name, Style::bold}});
223 err_text.emplace_back("");
224 params.emplace_back();
225
226 auto [format_text, format_params] = val.format_data();
227 err_text.append_range(format_text);
228 params.append_range(format_params);
229
230 err_text.emplace_back("");
231 params.emplace_back();
232 err_text.emplace_back("{}");
233 params.emplace_back(std::vector{FormatParam{"Comparison value:", Style::italic}});
234 err_text.emplace_back("");
235 params.emplace_back();
236
237 auto [other_format_text, other_format_params] = other_val.format_data();
238 err_text.append_range(other_format_text);
239 params.append_range(other_format_params);
240
241 return FormattableError{err_text, params};
242 }
243
244 return val;
245}
246
247} // namespace details
248
266template <typename T, typename ConfigInterface, typename FetchFunc>
268 const ConfigValue<T> &val,
269 const ConfigInterface &config,
270 ConfigScopeType type,
271 const std::string &scope,
272 const std::string &other_field_name,
273 FetchFunc fetch_other)
274{
276 val, config, type, scope, other_field_name, fetch_other, std::greater<>{}, "must be greater than");
277}
278
291template <typename T, typename ConfigInterface, typename FetchFunc>
293 const ConfigValue<T> &val,
294 const ConfigInterface &config,
295 ConfigScopeType type,
296 const std::string &scope,
297 const std::string &other_field_name,
298 FetchFunc fetch_other)
299{
301 val, config, type, scope, other_field_name, fetch_other, std::less<>{}, "must be less than");
302}
303
316template <typename T, typename ConfigInterface, typename FetchFunc>
318 const ConfigValue<T> &val,
319 const ConfigInterface &config,
320 ConfigScopeType type,
321 const std::string &scope,
322 const std::string &other_field_name,
323 FetchFunc fetch_other)
324{
326 val,
327 config,
328 type,
329 scope,
330 other_field_name,
331 fetch_other,
332 std::greater_equal<>{},
333 "must be greater than or equal to");
334}
335
348template <typename T, typename ConfigInterface, typename FetchFunc>
350 const ConfigValue<T> &val,
351 const ConfigInterface &config,
352 ConfigScopeType type,
353 const std::string &scope,
354 const std::string &other_field_name,
355 FetchFunc fetch_other)
356{
358 val, config, type, scope, other_field_name, fetch_other, std::less_equal<>{}, "must be less than or equal to");
359}
360
372template <typename T, typename ConfigInterface, typename FetchFunc>
374 const ConfigValue<T> &val,
375 const ConfigInterface &config,
376 const std::string &scope_param,
377 const std::string &other_field_name,
378 FetchFunc fetch_other)
379{
381 val, config, scope_param, other_field_name, fetch_other, std::equal_to<>{}, "must be equal to");
382}
383
395template <typename T, typename ConfigInterface, typename FetchFunc>
397 const ConfigValue<T> &val,
398 const ConfigInterface &config,
399 const std::string &scope_param,
400 const std::string &other_field_name,
401 FetchFunc fetch_other)
402{
404 val, config, scope_param, other_field_name, fetch_other, std::not_equal_to<>{}, "must not be equal to");
405}
406
407} // 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:57
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_one_two_or_four(const ConfigValue< std::size_t > &val)
Validates that a size_t config value is 1, 2, or 4.
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::optional< std::size_t > > > optional_size_t_val_one_two_or_four(const ConfigValue< std::optional< std::size_t > > &val)
Validates that an optional size_t config value, when set, is 1, 2, or 4.
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.