feat: add validator concept for clap
This commit is contained in:
@ -96,6 +96,7 @@ FILES
|
||||
yycc/carton/clap/summary.hpp
|
||||
yycc/carton/clap/application.hpp
|
||||
yycc/carton/clap/manual.hpp
|
||||
yycc/carton/clap/validator.hpp
|
||||
yycc/carton/fft.hpp
|
||||
)
|
||||
# Setup header infomations
|
||||
|
||||
@ -14,7 +14,7 @@ namespace yycc::carton::clap::application {
|
||||
NS_YYCC_CLAP::option::OptionCollection&& options,
|
||||
NS_YYCC_CLAP::variable::VariableCollection&& variables);
|
||||
~Application();
|
||||
YYCC_DEFAULT_COPY_MOVE(Application);
|
||||
YYCC_DEFAULT_COPY_MOVE(Application)
|
||||
|
||||
public:
|
||||
const NS_YYCC_CLAP::summary::Summary& get_summary() const;
|
||||
|
||||
@ -13,7 +13,7 @@ namespace yycc::carton::clap::manual {
|
||||
public:
|
||||
ManualTr();
|
||||
~ManualTr();
|
||||
YYCC_DEFAULT_COPY_MOVE(ManualTr);
|
||||
YYCC_DEFAULT_COPY_MOVE(ManualTr)
|
||||
|
||||
public:
|
||||
std::u8string author_and_version;
|
||||
@ -25,7 +25,7 @@ namespace yycc::carton::clap::manual {
|
||||
public:
|
||||
Manual(const NS_YYCC_CLAP::application::Application& app, ManualTr&& trctx = ManualTr());
|
||||
~Manual();
|
||||
YYCC_DEFAULT_COPY_MOVE(Manual);
|
||||
YYCC_DEFAULT_COPY_MOVE(Manual)
|
||||
|
||||
private:
|
||||
void setup_table();
|
||||
|
||||
79
src/yycc/carton/clap/validator.hpp
Normal file
79
src/yycc/carton/clap/validator.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
#include "../../num/parse.hpp"
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <limits>
|
||||
#include <concepts>
|
||||
#include <cmath>
|
||||
|
||||
#define NS_YYCC_NUM_PARSE ::yycc::num::parse
|
||||
|
||||
namespace yycc::carton::clap::validator {
|
||||
|
||||
/**
|
||||
* @brief The concept for checking whether given type is a valid command line argument validator.
|
||||
* @details
|
||||
* A valid command line argument validator must have a type name or alias called "ReturnType"
|
||||
* indicating the return value of this validator.
|
||||
*
|
||||
* And, it also should have an member function called "validate"
|
||||
* which receive <TT>const std::string_view&</TT> as its only argument,
|
||||
* and return <TT>std::optional<ReturnType></TT> as result.
|
||||
* If this \t std::optional is empty, it means that there is some error occurs when validating,
|
||||
* otherwise, it is the validated value.
|
||||
*/
|
||||
template<typename T>
|
||||
concept Validator = requires(const T& t, const std::u8string_view& sv) {
|
||||
// Check whether there is T::ReturnType type
|
||||
typename T::ReturnType;
|
||||
// Check whether there is "validate" member function and it has correct signature.
|
||||
{ t.validate(sv) } -> std::same_as<std::optional<typename T::ReturnType>>;
|
||||
};
|
||||
|
||||
template<std::integral T, auto TMin = std::numeric_limits<T>::min(), auto TMax = std::numeric_limits<T>::max()>
|
||||
struct IntegralValidator {
|
||||
static_assert(TMin <= TMax);
|
||||
using ReturnType = T;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) {
|
||||
auto rv = NS_YYCC_NUM_PARSE::parse<ReturnType>(sv);
|
||||
if (rv) {
|
||||
auto value = rv.value();
|
||||
if (value > TMax || value < TMin) return std::nullopt;
|
||||
else return value;
|
||||
} else return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
template<std::floating_point T, auto TMin = std::numeric_limits<T>::lowest(), auto TMax = std::numeric_limits<T>::max()>
|
||||
struct FloatingPointValidator {
|
||||
static_assert(std::isfinite(TMin));
|
||||
static_assert(std::isfinite(TMax));
|
||||
static_assert(TMin <= TMax);
|
||||
using ReturnType = T;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) {
|
||||
auto rv = NS_YYCC_NUM_PARSE::parse<ReturnType>(sv);
|
||||
if (rv) {
|
||||
auto value = rv.value();
|
||||
if (value > TMax || value < TMin) return std::nullopt;
|
||||
else return value;
|
||||
} else return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
struct BoolValidator {
|
||||
using ReturnType = bool;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) {
|
||||
auto rv = NS_YYCC_NUM_PARSE::parse<ReturnType>(sv);
|
||||
if (rv) return rv.value();
|
||||
else return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
struct StringValidator {
|
||||
using ReturnType = std::u8string;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) { return std::u8string(sv); }
|
||||
};
|
||||
|
||||
} // namespace yycc::carton::clap::validator
|
||||
|
||||
#undef NS_YYCC_NUM_PARSE
|
||||
Reference in New Issue
Block a user