2#ifndef _CONSOLIX_CLI_COMPONENT_HPP_INCLUDED
3#define _CONSOLIX_CLI_COMPONENT_HPP_INCLUDED
9#if CONSOLIX_USE_CXXOPTS == 1
22 class CliComponent :
public IAppComponent {
30 const std::string& name,
31 const std::string& description,
32 std::function<
void(CliOptions&)> creator)
33 : m_creator(std::move(creator)) {
34 register_options_service(name, description);
44 const std::string& name,
45 const std::string& description,
46 std::function<
void(CliOptions&)> creator,
49 : m_creator(std::move(creator)) {
50 register_options_service(name, description);
51 store_argv(argc, argv);
61 const std::string& name,
62 const std::string& description,
63 std::function<
void(CliOptions&)> creator,
66 : m_creator(std::move(creator)) {
67 register_options_service(name, description);
68 store_argv(argc, argv);
76 void add_option(
const std::string& key,
const std::string& description) {
77 get_service<CliOptions>().add_options()(key, description, cxxopts::value<T>());
86 void add_option(
const std::string& key,
const std::string& description, T default_value) {
87 get_service<CliOptions>().add_options()(key, description, cxxopts::value<T>()->default_value(std::to_string(default_value)));
96 void add_option_implicit(
const std::string& key,
const std::string& description, T implicit_value) {
97 get_service<CliOptions>().add_options()(key, description, cxxopts::value<T>()->implicit_value(std::to_string(implicit_value)));
103 void parse(
int argc,
const char* argv[]) {
105 auto result = get_service<CliOptions>().parse(argc, argv);
106 register_service<CliArguments>([&result](){
107 return std::make_shared<CliArguments>(result);
109 }
catch (
const std::exception& e) {
110 CONSOLIX_STREAM() <<
"Error parsing command-line arguments: " << e.what() << std::endl;
111# if CONSOLIX_USE_LOGIT == 1
112 LOGIT_PRINT_ERROR(
"Error parsing command-line arguments: ", e.what());
123 template <
typename T>
124 T get(
const std::string& key)
const {
125 if (!get_service<CliArguments>().count(key)) {
126# if CONSOLIX_USE_LOGIT == 1
127 LOGIT_PRINT_ERROR(
"Option not found: ", key);
129 throw std::runtime_error(
"Option not found: " + key);
131 return get_service<CliArguments>()[key].as<T>();
138 bool initialize()
override {
140 auto &options = get_service<CliOptions>();
142 throw std::runtime_error(
"CLI options creator function is null. Ensure you provide a valid function to initialize CLI options.");
145# if defined(_WIN32) || defined(_WIN64)
149 parse(m_argc, m_argv_c.data());
152 }
catch (
const std::exception& e) {
153# if CONSOLIX_USE_LOGIT == 1
154 LOGIT_PRINT_ERROR(
"CLI component initialization failed: ", e.what());
157 CONSOLIX_STREAM() <<
"Error initializing CLI component: " << e.what() << std::endl;
167 bool is_initialized()
const override {
172 void process()
override {}
176 std::vector<const char*> m_argv_c;
177 std::function<void(CliOptions&)> m_creator;
178 std::atomic<bool> m_is_init{
false};
181 void register_options_service(
const std::string& name,
const std::string& description) {
182 register_service<CliOptions>([&name, &description]() {
183 return std::make_shared<CliOptions>(name, description);
188 template <
typename ArgvEntry>
189 void store_argv(
int argc, ArgvEntry argv[]) {
191 for (
int i = 0; i < argc; ++i) {
192 m_argv_c.push_back(argv[i]);
196# if defined(_WIN32) || defined(_WIN64)
198 void parse_windows() {
200 LPWSTR* argv_w = CommandLineToArgvW(GetCommandLineW(), &argc);
202 std::vector<std::string> args;
203 for (
int i = 0; i < argc; ++i) {
204 args.push_back(utf16_to_utf8(argv_w[i]));
208 std::vector<const char*> argv_c;
209 for (
const auto& arg : args) {
210 argv_c.push_back(arg.c_str());
213 parse(argc, argv_c.data());
#define CONSOLIX_STREAM()
Fallback for general logging.
< Utility modules and helpers.