1
0

feat: add validator concept for clap

This commit is contained in:
2025-12-06 21:29:51 +08:00
parent ab8489c377
commit f76eabee7a
4 changed files with 83 additions and 3 deletions

View File

@ -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

View File

@ -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;

View File

@ -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();

View 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