22#include "rpc/common/APIVersion.hpp"
23#include "util/config/Error.hpp"
24#include "util/config/Types.hpp"
25#include "util/log/Logger.hpp"
27#include <fmt/format.h>
28#include <fmt/ranges.h>
41namespace util::config {
48static constexpr std::array<char const*, 6> kLOG_LEVELS = {
60static constexpr std::array<char const*, 5> kLOG_TAGS = {
71static constexpr std::array<char const*, 3> kLOAD_CACHE_MODE = {
80static constexpr std::array<char const*, 1> kDATABASE_TYPE = {
"cassandra"};
85static constexpr std::array<char const*, 2> kPROCESSING_POLICY = {
"parallel",
"sequent"};
104 if (
auto const maybeError =
checkTypeImpl(val); maybeError.has_value())
119 template <std::
size_t ArrSize>
120 constexpr std::string
121 makeErrorMsg(std::string_view key, Value
const& value, std::array<char const*, ArrSize> arr)
const
124 auto const valueStr = std::visit([](
auto const& v) {
return fmt::format(
"{}", v); }, value);
128 R
"(You provided value "{}". Key "{}"'s value must be one of the following: {})",
141 virtual std::optional<Error>
150 virtual std::optional<Error>
159 print(std::ostream& stream)
const = 0;
190 [[nodiscard]] std::optional<Error>
191 checkTypeImpl(Value
const& port)
const override;
199 [[nodiscard]] std::optional<Error>
200 checkValueImpl(Value
const& port)
const override;
208 print(std::ostream& stream)
const override
210 stream << fmt::format(
"The minimum value is `{}`. The maximum value is `{}`.", kPORT_MIN, kPORT_MAX);
213 static constexpr uint32_t kPORT_MIN = 1;
214 static constexpr uint32_t kPORT_MAX = 65535;
231 [[nodiscard]] std::optional<Error>
232 checkTypeImpl(Value
const& ip)
const override;
240 [[nodiscard]] std::optional<Error>
241 checkValueImpl(Value
const& ip)
const override;
249 print(std::ostream& stream)
const override
251 stream <<
"The value must be a valid IP address.";
260template <std::
size_t ArrSize>
269 constexpr OneOf(std::string_view key, std::array<char const*, ArrSize> arr) : key_{key}, arr_{arr}
273 constexpr ~OneOf() noexcept override = default;
282 [[nodiscard]] std::optional<
Error>
283 checkTypeImpl(Value const& val)
const override
285 if (!std::holds_alternative<std::string>(val))
286 return Error{fmt::format(R
"(Key "{}"'s value must be a string)", key_)};
296 [[nodiscard]] std::optional<Error>
297 checkValueImpl(Value
const& val)
const override
299 namespace rg = std::ranges;
300 auto const check = [&val](std::string_view name) {
return std::get<std::string>(val) == name; };
301 if (rg::any_of(arr_, check))
313 print(std::ostream& stream)
const override
315 std::string valuesStream;
316 std::ranges::for_each(arr_, [&valuesStream](std::string
const& elem) {
317 valuesStream += fmt::format(
" `{}`,", elem);
320 valuesStream.back() =
'.';
321 stream << fmt::format(
"The value must be one of the following:{}", valuesStream);
324 std::string_view key_;
325 std::array<char const*, ArrSize> arr_;
331template <
typename NumType>
353 [[nodiscard]] std::optional<
Error>
354 checkTypeImpl(Value const& num)
const override
356 if (!std::holds_alternative<int64_t>(num))
357 return Error{
"Number must be of type integer"};
367 [[nodiscard]] std::optional<Error>
368 checkValueImpl(Value
const& num)
const override
370 auto const numValue = std::get<int64_t>(num);
371 if (numValue >=
static_cast<int64_t
>(min_) && numValue <=
static_cast<int64_t
>(max_))
373 return Error{fmt::format(
"Number must be between {} and {}", min_, max_)};
382 print(std::ostream& stream)
const override
384 stream << fmt::format(
"The minimum value is `{}`. The maximum value is `{}`.", min_, max_);
405 [[nodiscard]] std::optional<Error>
406 checkTypeImpl(Value
const& num)
const override;
414 [[nodiscard]] std::optional<Error>
415 checkValueImpl(Value
const& num)
const override;
423 print(std::ostream& stream)
const override
425 stream <<
"The value must be a positive double number.";
440 [[nodiscard]] std::optional<Error>
441 checkTypeImpl(Value
const& value)
const override;
449 [[nodiscard]] std::optional<Error>
450 checkValueImpl(Value
const& value)
const override;
458 print(std::ostream& stream)
const override
460 stream <<
"Checks whether provided RPC name is valid";
465static constinit ValidIPConstraint gValidateIp{};
467static constinit OneOf gValidateChannelName{
"channel", Logger::kCHANNELS};
468static constinit OneOf gValidateLogLevelName{
"log_level", kLOG_LEVELS};
469static constinit OneOf gValidateCassandraName{
"database.type", kDATABASE_TYPE};
470static constinit OneOf gValidateLoadMode{
"cache.load", kLOAD_CACHE_MODE};
471static constinit OneOf gValidateLogTag{
"log_tag_style", kLOG_TAGS};
472static constinit OneOf gValidateProcessingPolicy{
"server.processing_policy", kPROCESSING_POLICY};
474static constinit PositiveDouble gValidatePositiveDouble{};
476static constinit NumberValueConstraint<uint16_t> gValidateNumMarkers{1, 256};
477static constinit NumberValueConstraint<uint16_t> gValidateNumCursors{0, std::numeric_limits<uint16_t>::max()};
480static constinit NumberValueConstraint<uint16_t> gValidateReplicationFactor{0, std::numeric_limits<uint16_t>::max()};
482static constinit NumberValueConstraint<uint16_t> gValidateUint16{1, std::numeric_limits<uint16_t>::max()};
484static constinit NumberValueConstraint<uint32_t> gValidateUint32{1, std::numeric_limits<uint32_t>::max()};
485static constinit NumberValueConstraint<uint32_t> gValidateNonNegativeUint32{0, std::numeric_limits<uint32_t>::max()};
488static constinit RpcNameConstraint gRpcNameConstraint{};
An interface to enforce constraints on certain values within ClioConfigDefinition.
Definition ConfigConstraints.hpp:90
friend std::ostream & operator<<(std::ostream &stream, Constraint const &cons)
Custom output stream for constraint.
Definition ConfigConstraints.hpp:169
virtual void print(std::ostream &stream) const =0
Prints to the output stream for this specific constraint.
virtual std::optional< Error > checkValueImpl(Value const &val) const =0
Check if the value is within the constraint.
std::optional< Error > checkConstraint(Value const &val) const
Check if the value meets the specific constraint.
Definition ConfigConstraints.hpp:102
constexpr std::string makeErrorMsg(std::string_view key, Value const &value, std::array< char const *, ArrSize > arr) const
Creates an error message for all constraints that must satisfy certain hard-coded values.
Definition ConfigConstraints.hpp:121
virtual std::optional< Error > checkTypeImpl(Value const &val) const =0
Check if the value is of a correct type for the constraint.
A constraint class to ensure an integer value is between two numbers (inclusive)
Definition ConfigConstraints.hpp:332
constexpr NumberValueConstraint(NumType min, NumType max)
Constructs a constraint where the number must be between min_ and max_.
Definition ConfigConstraints.hpp:340
A constraint class to ensure the provided value is one of the specified values in an array.
Definition ConfigConstraints.hpp:261
constexpr OneOf(std::string_view key, std::array< char const *, ArrSize > arr)
Constructs a constraint where the value must be one of the values in the provided array.
Definition ConfigConstraints.hpp:269
A constraint to ensure the port number is within a valid range.
Definition ConfigConstraints.hpp:179
A constraint to ensure a double number is positive.
Definition ConfigConstraints.hpp:394
A constraint to ensure the value is a valid RPC command name.
Definition ConfigConstraints.hpp:432
A constraint to ensure the IP address is valid.
Definition ConfigConstraints.hpp:220
static constexpr uint32_t kAPI_VERSION_MIN
Minimum API version supported by this build.
Definition APIVersion.hpp:38
static constexpr uint32_t kAPI_VERSION_MAX
Maximum API version supported by this build.
Definition APIVersion.hpp:43
Displays the different errors when parsing user config.
Definition Error.hpp:31