1
0

test: basically finish clap test.

- basically finish clap test (except variable part)
- fix some clap issue (still have some bugs)
This commit is contained in:
2025-12-11 15:21:59 +08:00
parent 79e8af89fe
commit 6a97b13f66
8 changed files with 372 additions and 35 deletions

View File

@ -41,7 +41,7 @@ PRIVATE
yycc/carton/binstore/types.cpp
yycc/carton/binstore/setting.cpp
yycc/carton/binstore/configuration.cpp
yycc/carton/binstore/storage.cpp
#yycc/carton/binstore/storage.cpp
)
target_sources(YYCCommonplace
PUBLIC
@ -110,7 +110,7 @@ FILES
yycc/carton/binstore/serializer.hpp
yycc/carton/binstore/setting.hpp
yycc/carton/binstore/configuration.hpp
yycc/carton/binstore/storage.hpp
#yycc/carton/binstore/storage.hpp
yycc/carton/fft.hpp
)
# Setup header infomations

View File

@ -84,8 +84,9 @@ namespace yycc::carton::binstore::serializer {
struct FloatingPointSerDes {
YYCC_DEFAULT_COPY_MOVE(FloatingPointSerDes)
static_assert(std::isfinite(TMin));
static_assert(std::isfinite(TMax));
// TODO: Use static_assert once 3 common STL make this become constexpr.
//static_assert(std::isfinite(TMin));
//static_assert(std::isfinite(TMax));
static_assert(TMin <= TMax);
static_assert(TDefault >= TMin && TDefault <= TMax);

View File

@ -11,15 +11,37 @@
#include <ostream>
#define NS_YYCC_BINSTORE_TYPES ::yycc::carton::binstore::types
#define NS_YYCC_BINSTORE_SERIALIZER ::yycc::carton::binstore::serializer
#define NS_YYCC_BINSTORE_CFG ::yycc::carton::binstore::configuration
#define NS_YYCC_BINSTORE_SERDES ::yycc::carton::binstore::serializer
namespace yycc::carton::binstore::storage {
/// @brief The strategy when loading from storage.
enum class LoadStrategy {
OnlyCurrent, ///< Only the file with exactly matched version identifier can be loaded. Any other version will cause load error.
LegacyAndCurrent, ///< Accept all old version and current version. Any other version will cause load error.
AcceptAll, ///< Accept all versions.
/**
* @brief Only accept matched version.
* @details
* Any loading of other versions will explicitly cause error return.
* This is convenient for developer who want control migration by themselves.
* They can specify this strategy and try to load data with different version configurations
* from older to newer one by one.
*/
OnlyCurrent,
/**
* @brief Try to migrate old version.
* @details
* Accept mateched and any older versions.
* Any newer versions will explicitly cause error return.
* This strategy is good for developer who are lazy to treat this manually.
*/
MigrateOld,
/**
* @brief Accept all version.
* @details
* This strategy is not suggested.
* This strategy only suit for quick demo.
*/
AcceptAll,
};
/// @brief The operation result state when getting setting's value.
@ -38,11 +60,12 @@ namespace yycc::carton::binstore::storage {
class Storage {
private:
/**
* @brief All stored settings in raw format.
* @brief All stored values of setting in raw format.
* @details Key is the token to already registered settings.
* Valus is its stored value in raw data format.
*/
std::map<NS_YYCC_BINSTORE_TYPES::Token, NS_YYCC_BINSTORE_TYPES::ByteArray> raws;
NS_YYCC_BINSTORE_CFG::Configuration configuration; ///< The configuration associated with this storage.
public:
Storage();
@ -50,38 +73,78 @@ namespace yycc::carton::binstore::storage {
public:
NS_YYCC_BINSTORE_TYPES::BinstoreResult<void> load_from_file(const std::filesystem::path& fpath, LoadStrategy strategy);
NS_YYCC_BINSTORE_TYPES::BinstoreResult<void> load_from_io(const std::istream& s, LoadStrategy strategy);
NS_YYCC_BINSTORE_TYPES::BinstoreResult<void> load_from_io(std::istream& s, LoadStrategy strategy);
NS_YYCC_BINSTORE_TYPES::BinstoreResult<void> save_into_file(const std::filesystem::path& fpath);
NS_YYCC_BINSTORE_TYPES::BinstoreResult<void> save_into_io(const std::ostream& s);
NS_YYCC_BINSTORE_TYPES::BinstoreResult<void> save_into_io(std::ostream& s);
/**
* @brief Reset all values of setting to their default value.
* @details Please note that all stored value will be wiped before assign them with default value.65
*/
void reset();
private:
bool has_value(NS_YYCC_BINSTORE_TYPES::Token token) const;
std::optional<NS_YYCC_BINSTORE_TYPES::ByteArray> get_raw_value(NS_YYCC_BINSTORE_TYPES::Token token) const;
const NS_YYCC_BINSTORE_TYPES::ByteArray& get_raw_value(NS_YYCC_BINSTORE_TYPES::Token token) const;
void set_raw_value(NS_YYCC_BINSTORE_TYPES::Token token, NS_YYCC_BINSTORE_TYPES::ByteArray&& ba);
public:
template<NS_YYCC_BINSTORE_SERIALIZER::SerDes T>
NS_YYCC_BINSTORE_TYPES::BinstoreResult<std::pair<GetValueState, NS_YYCC_BINSTORE_SERIALIZER::SerDesValueType<T>>> get_value(
template<NS_YYCC_BINSTORE_SERDES::SerDes T>
NS_YYCC_BINSTORE_TYPES::BinstoreResult<std::pair<GetValueState, NS_YYCC_BINSTORE_SERDES::SerDesValueType<T>>> get_value(
NS_YYCC_BINSTORE_TYPES::Token token, const T& serdes = T()) {
// Fetch from raw value.
auto rv_raw_value = this->get_raw_value(token);
if (!rv_raw_value.has_value()) return std::unexpected(rv_raw_value.error());
auto& [state, raw_value] = rv_raw_value.value();
// If we have value, we fetch it first
if (this->has_value(token)) {
// Get raw value.
const auto& ba = this->get_raw_value(token);
// Try to deserialize it.
auto value = serdes.deserialize(raw_value);
// If the result is okey, return it.
if (value.has_value()) {
return std::make_pair(GetValueState::Ok, std::move(value.value()));
}
// Otherwise we need reset it into default value.
}
// Pass into deserializer.
auto rv_des = serdes.deserialize(raw_value);
if (rv_des.has_value()) return rv_des.value();
// If we can not set it, we force reset it and try again.
this->set_raw_value()
// If we do not have this setting,
// or we need reset it into default value,
// we need execute following code.
// First decide the return state.
GetValueState state = this->has_value(token) ? GetValueState::Reset : GetValueState::Default;
{
// Fetch the default raw data.
auto ba = serdes.reset();
// Set it for this setting.
this->set_raw_value(token, std::move(ba));
}
// The get it and deserialize it.
const auto& ba = this->get_raw_value(token);
auto value = serdes.deserialize(ba);
// Default must can be deserialized.
// If not, throw exception.
if (value.has_value()) {
return std::make_pair(state, std::move(value));
} else {
throw std::logic_error("default value can not be deserialized");
}
}
template<NS_YYCC_BINSTORE_SERIALIZER::SerDes T>
template<NS_YYCC_BINSTORE_SERDES::SerDes T>
NS_YYCC_BINSTORE_TYPES::BinstoreResult<SetValueState> set_value(NS_YYCC_BINSTORE_TYPES::Token token,
const NS_YYCC_BINSTORE_SERIALIZER::SerDesValueType<T>& value,
const NS_YYCC_BINSTORE_SERDES::SerDesValueType<T>& value,
const T& serdes = T()) {
// First we try assign it.
{
// Convert it into raw format.
auto ba = serdes.serialize(value);
// If we can not serialize it, we need reset it into default value.
// Otherwise assign it and return.
if (ba.has_value()) {
this->set_raw_value(token, )
}
}
}
};
} // namespace yycc::carton::binstore::storage
#undef NS_YYCC_BINSTORE_SERDES
#undef NS_YYCC_BINSTORE_CFG
#undef NS_YYCC_BINSTORE_TYPES

View File

@ -45,8 +45,8 @@ namespace yycc::carton::clap::parser {
bool has_option(NS_YYCC_CLAP_TYPES::Token token) const;
NS_YYCC_CLAP_TYPES::ClapResult<bool> get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const;
template<NS_YYCC_CLAP_VALIDATOR::Validator T>
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_option(
NS_YYCC_CLAP_TYPES::Token token, const T& validator = T()) const {
NS_YYCC_CLAP_TYPES::ClapResult<NS_YYCC_CLAP_VALIDATOR::ValidatorReturnType<T>> get_value_option(NS_YYCC_CLAP_TYPES::Token token,
const T& validator = T()) const {
auto raw_value = this->get_raw_value_option(token);
if (raw_value.has_value()) {
auto value = validator.validate(raw_value.value());

View File

@ -47,7 +47,7 @@ namespace yycc::carton::clap::validator {
static_assert(TMin <= TMax);
using ReturnType = T;
std::optional<ReturnType> validate(const std::u8string_view& sv) {
std::optional<ReturnType> validate(const std::u8string_view& sv) const {
auto rv = NS_YYCC_NUM_PARSE::parse<ReturnType>(sv);
if (rv) {
auto value = rv.value();
@ -61,12 +61,13 @@ namespace yycc::carton::clap::validator {
struct FloatingPointValidator {
YYCC_DEFAULT_COPY_MOVE(FloatingPointValidator)
static_assert(std::isfinite(TMin));
static_assert(std::isfinite(TMax));
// TODO: Use static_assert once 3 common STL make this become constexpr.
//static_assert(std::isfinite<T>(TMin));
//static_assert(std::isfinite<T>(TMax));
static_assert(TMin <= TMax);
using ReturnType = T;
std::optional<ReturnType> validate(const std::u8string_view& sv) {
std::optional<ReturnType> validate(const std::u8string_view& sv) const {
auto rv = NS_YYCC_NUM_PARSE::parse<ReturnType>(sv);
if (rv) {
auto value = rv.value();
@ -80,7 +81,7 @@ namespace yycc::carton::clap::validator {
YYCC_DEFAULT_COPY_MOVE(BoolValidator)
using ReturnType = bool;
std::optional<ReturnType> validate(const std::u8string_view& sv) {
std::optional<ReturnType> validate(const std::u8string_view& sv) const {
auto rv = NS_YYCC_NUM_PARSE::parse<ReturnType>(sv);
if (rv) return rv.value();
else return std::nullopt;
@ -91,7 +92,7 @@ namespace yycc::carton::clap::validator {
YYCC_DEFAULT_COPY_MOVE(StringValidator)
using ReturnType = std::u8string;
std::optional<ReturnType> validate(const std::u8string_view& sv) { return std::u8string(sv); }
std::optional<ReturnType> validate(const std::u8string_view& sv) const { return std::u8string(sv); }
};
} // namespace yycc::carton::clap::validator