feat: update cli for BMapInspector
This commit is contained in:
@@ -8,31 +8,61 @@
|
||||
#include <yycc/string/op.hpp>
|
||||
#include <yycc/patch/stream.hpp>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
using namespace yycc::patch::stream;
|
||||
namespace strop = yycc::string::op;
|
||||
namespace termcolor = yycc::carton::termcolor;
|
||||
|
||||
static bool ProcessCli() {
|
||||
|
||||
}
|
||||
|
||||
static void LoadVirtools() {
|
||||
|
||||
}
|
||||
|
||||
static void CheckRules() {
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// Show splash
|
||||
static void PrintSplash() {
|
||||
std::cout << termcolor::colored(u8"" BMAPINSP_NAME, termcolor::Color::LightYellow)
|
||||
<< " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__ << std::endl
|
||||
<< u8"" BMAPINSP_DESC << std::endl
|
||||
<< std::endl;
|
||||
<< u8"" BMAPINSP_DESC << std::endl;
|
||||
}
|
||||
|
||||
static std::optional<BMapInspector::Cli::Args> AcceptArgs() {
|
||||
auto request = BMapInspector::Cli::parse();
|
||||
if (request.has_value()) {
|
||||
return request.value();
|
||||
} else {
|
||||
using BMapInspector::Cli::Error;
|
||||
|
||||
std::u8string bad_words;
|
||||
switch (request.error()) {
|
||||
case Error::BadParse:
|
||||
bad_words = u8"Can not parse given command line argument."; break;
|
||||
case Error::NoFile:
|
||||
bad_words = u8"You must specify a file for checking.";
|
||||
break;
|
||||
case Error::BadFile:
|
||||
bad_words = u8"Your specified file is invalid.";
|
||||
break;
|
||||
case Error::NoBallance:
|
||||
bad_words = u8"You must specify Ballance root directory for finding resources.";
|
||||
break;
|
||||
case Error::BadBallance:
|
||||
bad_words = u8"Your specified Ballance root directory is invalid.";
|
||||
break;
|
||||
case Error::BadEncoding:
|
||||
bad_words = u8"Your specified encoding name is invalid.";
|
||||
break;
|
||||
case Error::BadLevel:
|
||||
bad_words = u8"Your specified report level filter name is invalid.";
|
||||
break;
|
||||
default:
|
||||
bad_words = u8"Unknown error.";
|
||||
break;
|
||||
}
|
||||
|
||||
termcolor::cprintln(bad_words, termcolor::Color::Red);
|
||||
termcolor::cprintln(u8"Please browse manual or use -h switch to see help first.", termcolor::Color::Red);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadVirtools() {}
|
||||
|
||||
static void CheckRules() {
|
||||
// Create reporter
|
||||
BMapInspector::Reporter reporter;
|
||||
|
||||
@@ -40,13 +70,21 @@ int main(int argc, char *argv[]) {
|
||||
BMapInspector::Ruleset::RuleCollection rule_collection;
|
||||
// Show rule infos
|
||||
std::cout << strop::printf(u8"Total %" PRIuSIZET " rule(s) are loaded.", rule_collection.GetRuleCount()) << std::endl
|
||||
<< u8"Check may take few minutes. Please do not close this console..." << std::endl
|
||||
<< std::endl;
|
||||
|
||||
<< u8"Check may take few minutes. Please do not close this console..." << std::endl;
|
||||
|
||||
// Show report conclusion
|
||||
reporter.PrintConclusion();
|
||||
// Print report in detail
|
||||
reporter.PrintReport();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
auto args = AcceptArgs();
|
||||
if (args.has_value()) {
|
||||
PrintSplash();
|
||||
std::cout << std::endl;
|
||||
|
||||
CheckRules();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,63 +1,12 @@
|
||||
#include "Cli.hpp"
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/carton/clap.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace clap = yycc::carton::clap;
|
||||
|
||||
namespace BMapInspector::Cli {
|
||||
|
||||
#pragma region Request
|
||||
|
||||
Request Request::FromHelpRequest() {
|
||||
return Request(RequestKind::Help, std::nullopt, std::nullopt, std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
Request Request::FromVersionRequest() {
|
||||
return Request(RequestKind::Version, std::nullopt, std::nullopt, std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
Request Request::FromWorkRequest(Utils::ReportLevel level,
|
||||
const std::u8string_view& file_path,
|
||||
const std::u8string_view& encoding,
|
||||
const std::u8string_view& ballance_path) {
|
||||
return Request(RequestKind::Work, level, file_path, encoding, ballance_path);
|
||||
}
|
||||
|
||||
Request::Request(RequestKind kind,
|
||||
std::optional<Utils::ReportLevel> level,
|
||||
std::optional<std::u8string_view> file_path,
|
||||
std::optional<std::u8string_view> encoding,
|
||||
std::optional<std::u8string_view> ballance_path) :
|
||||
kind(kind), level(level), file_path(file_path), encoding(encoding), ballance_path(ballance_path) {}
|
||||
|
||||
Request::~Request() {}
|
||||
|
||||
RequestKind Request::GetRequestKind() const {
|
||||
return this->kind;
|
||||
}
|
||||
|
||||
Utils::ReportLevel Request::GetLevel() const {
|
||||
if (this->level.has_value()) return this->level.value();
|
||||
else throw std::logic_error("can not visit this property in current kind");
|
||||
}
|
||||
|
||||
std::u8string_view Request::GetFilePath() const {
|
||||
if (this->file_path.has_value()) return this->file_path.value();
|
||||
else throw std::logic_error("can not visit this property in current kind");
|
||||
}
|
||||
|
||||
std::u8string_view Request::GetEncoding() const {
|
||||
if (this->encoding.has_value()) return this->encoding.value();
|
||||
else throw std::logic_error("can not visit this property in current kind");
|
||||
}
|
||||
|
||||
std::u8string_view Request::GetBallancePath() const {
|
||||
if (this->ballance_path.has_value()) return this->ballance_path.value();
|
||||
else throw std::logic_error("can not visit this property in current kind");
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Custom Validators
|
||||
|
||||
struct ReportLevelValidator {
|
||||
@@ -65,10 +14,36 @@ namespace BMapInspector::Cli {
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) const { return Utils::ParseReportLevel(sv); }
|
||||
};
|
||||
|
||||
struct MapFileValidator {
|
||||
using ReturnType = std::u8string;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) const {
|
||||
std::filesystem::path p(sv);
|
||||
if (std::filesystem::is_regular_file(p)) return std::u8string(sv);
|
||||
else return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
struct BlcDirValidator {
|
||||
using ReturnType = std::u8string;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) const {
|
||||
std::filesystem::path p(sv);
|
||||
auto tdb = p / u8"Database.tdb";
|
||||
if (std::filesystem::is_directory(p) && std::filesystem::is_regular_file(tdb)) return std::u8string(sv);
|
||||
else return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
struct EncNameValidator {
|
||||
using ReturnType = std::u8string;
|
||||
std::optional<ReturnType> validate(const std::u8string_view& sv) const {
|
||||
// TODO: use checker for checking this name first.
|
||||
return std::u8string(sv);
|
||||
}
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
Result<Request> parse() {
|
||||
Result<std::optional<Args>> parse() {
|
||||
// Create options
|
||||
clap::option::OptionCollection opt_collection;
|
||||
auto opt_file = opt_collection.add_option(
|
||||
@@ -94,6 +69,8 @@ Default value is "info".)"));
|
||||
clap::summary::Summary summary(u8"" BMAPINSP_NAME, u8"yyc12345", u8"Universal", u8"" BMAPINSP_DESC);
|
||||
// Create application
|
||||
clap::application::Application app(std::move(summary), std::move(opt_collection), std::move(var_collection));
|
||||
// Create manual
|
||||
clap::manual::Manual manual(app);
|
||||
|
||||
// Create parser and parse command line arguments
|
||||
auto rv_parser = clap::parser::Parser::from_system(app);
|
||||
@@ -101,17 +78,19 @@ Default value is "info".)"));
|
||||
auto& parser = rv_parser.value();
|
||||
|
||||
// Check version and help first
|
||||
if (auto help_flag = parser.get_flag_option(opt_help); help_flag.has_value()) {
|
||||
return Request::FromHelpRequest();
|
||||
if (auto help_flag = parser.get_flag_option(opt_help); help_flag.has_value() && help_flag.value()) {
|
||||
manual.print_help();
|
||||
return std::nullopt;
|
||||
}
|
||||
if (auto version_flag = parser.get_flag_option(opt_version); version_flag.has_value()) {
|
||||
return Request::FromVersionRequest();
|
||||
if (auto version_flag = parser.get_flag_option(opt_version); version_flag.has_value() && version_flag.value()) {
|
||||
manual.print_version();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Check other args
|
||||
std::u8string file_rv;
|
||||
if (parser.has_option(opt_file)) {
|
||||
auto file_value = parser.get_value_option<clap::validator::StringValidator>(opt_file);
|
||||
auto file_value = parser.get_value_option<MapFileValidator>(opt_file);
|
||||
if (!file_value.has_value()) return std::unexpected(Error::BadFile);
|
||||
file_rv = std::move(file_value.value());
|
||||
} else {
|
||||
@@ -119,7 +98,7 @@ Default value is "info".)"));
|
||||
}
|
||||
std::u8string ballance_rv;
|
||||
if (parser.has_option(opt_ballance)) {
|
||||
auto ballance_value = parser.get_value_option<clap::validator::StringValidator>(opt_ballance);
|
||||
auto ballance_value = parser.get_value_option<BlcDirValidator>(opt_ballance);
|
||||
if (!ballance_value.has_value()) return std::unexpected(Error::BadBallance);
|
||||
ballance_rv = std::move(ballance_value.value());
|
||||
} else {
|
||||
@@ -127,7 +106,7 @@ Default value is "info".)"));
|
||||
}
|
||||
std::u8string encoding_rv;
|
||||
if (parser.has_option(opt_encoding)) {
|
||||
auto encoding_value = parser.get_value_option<clap::validator::StringValidator>(opt_encoding);
|
||||
auto encoding_value = parser.get_value_option<EncNameValidator>(opt_encoding);
|
||||
if (!encoding_value.has_value()) return std::unexpected(Error::BadEncoding);
|
||||
encoding_rv = std::move(encoding_value.value());
|
||||
} else {
|
||||
@@ -143,7 +122,12 @@ Default value is "info".)"));
|
||||
}
|
||||
|
||||
// Return result
|
||||
return Request::FromWorkRequest(level_rv, file_rv, encoding_rv, ballance_rv);
|
||||
return Args{
|
||||
.level = level_rv,
|
||||
.file_path = file_rv,
|
||||
.encoding = encoding_rv,
|
||||
.ballance_path = ballance_rv,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace BMapInspector::Cli
|
||||
|
||||
@@ -9,45 +9,11 @@
|
||||
|
||||
namespace BMapInspector::Cli {
|
||||
|
||||
enum class RequestKind {
|
||||
Help,
|
||||
Version,
|
||||
Work,
|
||||
};
|
||||
|
||||
class Request {
|
||||
public:
|
||||
static Request FromHelpRequest();
|
||||
static Request FromVersionRequest();
|
||||
static Request FromWorkRequest(Utils::ReportLevel level,
|
||||
const std::u8string_view& file_path,
|
||||
const std::u8string_view& encoding,
|
||||
const std::u8string_view& ballance_path);
|
||||
|
||||
private:
|
||||
Request(RequestKind kind,
|
||||
std::optional<Utils::ReportLevel> level,
|
||||
std::optional<std::u8string_view> file_path,
|
||||
std::optional<std::u8string_view> encoding,
|
||||
std::optional<std::u8string_view> ballance_path);
|
||||
|
||||
public:
|
||||
~Request();
|
||||
YYCC_DEFAULT_COPY_MOVE(Request)
|
||||
|
||||
public:
|
||||
RequestKind GetRequestKind() const;
|
||||
Utils::ReportLevel GetLevel() const;
|
||||
std::u8string_view GetFilePath() const;
|
||||
std::u8string_view GetEncoding() const;
|
||||
std::u8string_view GetBallancePath() const;
|
||||
|
||||
private:
|
||||
RequestKind kind; ///< The kind of this request.
|
||||
std::optional<Utils::ReportLevel> level; ///< The filter level.
|
||||
std::optional<std::u8string> file_path; ///< The path to loaded map file.
|
||||
std::optional<std::u8string> encoding; ///< The encoding used when loading map file.
|
||||
std::optional<std::u8string> ballance_path; ///< The path to Ballance root directory for loading resources.
|
||||
struct Args {
|
||||
Utils::ReportLevel level; ///< The filter level.
|
||||
std::u8string file_path; ///< The path to loaded map file.
|
||||
std::u8string encoding; ///< The encoding used when loading map file.
|
||||
std::u8string ballance_path; ///< The path to Ballance root directory for loading resources.
|
||||
};
|
||||
|
||||
enum class Error {
|
||||
@@ -63,6 +29,6 @@ namespace BMapInspector::Cli {
|
||||
template<typename T>
|
||||
using Result = std::expected<T, Error>;
|
||||
|
||||
Result<Request> parse();
|
||||
Result<std::optional<Args>> parse();
|
||||
|
||||
} // namespace BMapInspector::Cli
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Utils.hpp"
|
||||
#include "Reporter.hpp"
|
||||
#include <VTAll.hpp>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/class_copy_move.hpp>
|
||||
@@ -17,7 +18,7 @@ namespace BMapInspector::Ruleset {
|
||||
|
||||
public:
|
||||
virtual std::u8string_view GetRuleName() const = 0;
|
||||
virtual void Check(Utils::Reporter& reporter) const = 0;
|
||||
virtual void Check(Reporter& reporter) const = 0;
|
||||
};
|
||||
|
||||
class RuleCollection {
|
||||
|
||||
Reference in New Issue
Block a user