feat: add validator concept for clap
This commit is contained in:
@ -96,6 +96,7 @@ FILES
|
|||||||
yycc/carton/clap/summary.hpp
|
yycc/carton/clap/summary.hpp
|
||||||
yycc/carton/clap/application.hpp
|
yycc/carton/clap/application.hpp
|
||||||
yycc/carton/clap/manual.hpp
|
yycc/carton/clap/manual.hpp
|
||||||
|
yycc/carton/clap/validator.hpp
|
||||||
yycc/carton/fft.hpp
|
yycc/carton/fft.hpp
|
||||||
)
|
)
|
||||||
# Setup header infomations
|
# Setup header infomations
|
||||||
|
|||||||
@ -14,7 +14,7 @@ namespace yycc::carton::clap::application {
|
|||||||
NS_YYCC_CLAP::option::OptionCollection&& options,
|
NS_YYCC_CLAP::option::OptionCollection&& options,
|
||||||
NS_YYCC_CLAP::variable::VariableCollection&& variables);
|
NS_YYCC_CLAP::variable::VariableCollection&& variables);
|
||||||
~Application();
|
~Application();
|
||||||
YYCC_DEFAULT_COPY_MOVE(Application);
|
YYCC_DEFAULT_COPY_MOVE(Application)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const NS_YYCC_CLAP::summary::Summary& get_summary() const;
|
const NS_YYCC_CLAP::summary::Summary& get_summary() const;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace yycc::carton::clap::manual {
|
|||||||
public:
|
public:
|
||||||
ManualTr();
|
ManualTr();
|
||||||
~ManualTr();
|
~ManualTr();
|
||||||
YYCC_DEFAULT_COPY_MOVE(ManualTr);
|
YYCC_DEFAULT_COPY_MOVE(ManualTr)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::u8string author_and_version;
|
std::u8string author_and_version;
|
||||||
@ -25,7 +25,7 @@ namespace yycc::carton::clap::manual {
|
|||||||
public:
|
public:
|
||||||
Manual(const NS_YYCC_CLAP::application::Application& app, ManualTr&& trctx = ManualTr());
|
Manual(const NS_YYCC_CLAP::application::Application& app, ManualTr&& trctx = ManualTr());
|
||||||
~Manual();
|
~Manual();
|
||||||
YYCC_DEFAULT_COPY_MOVE(Manual);
|
YYCC_DEFAULT_COPY_MOVE(Manual)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup_table();
|
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