From 20640e766ef6d629acbc6c4c5dcdcd2e6599c299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=88=D0=B5=20=D0=98=D0=BC=D1=8F?= Date: Sun, 5 Oct 2025 14:13:52 +0400 Subject: [PATCH] refactor(cli): improve option handling with defaults and protected inheritance Update OptionUtils to include name placeholders for default values, switch cli classes to protected inheritance, and use at() for safer option retrieval. --- src/client/echo_client_cli.cpp | 17 ++++++++--------- src/client/echo_client_cli.hpp | 3 ++- src/common/option_utils.hpp | 10 ++++++++-- src/common/option_utils.tpp | 11 ++++++++--- src/common/server.hpp | 9 --------- src/server/echo_server_cli.cpp | 11 +++++------ src/server/echo_server_cli.hpp | 2 +- 7 files changed, 32 insertions(+), 31 deletions(-) delete mode 100644 src/common/server.hpp diff --git a/src/client/echo_client_cli.cpp b/src/client/echo_client_cli.cpp index e5b0449..b1fd003 100644 --- a/src/client/echo_client_cli.cpp +++ b/src/client/echo_client_cli.cpp @@ -1,4 +1,5 @@ #include "echo_client_cli.hpp" +#include EchoClientCli::EchoClientCli() : CliBase("Echo Client Options") @@ -12,24 +13,22 @@ void EchoClientCli::setupOptions() { // clang-format off desc_.add_options() - ("help,h", "Show help") - ("host,H", withDefault(host_), "Server host (IP or DNS name)") - ("port,p", withDefault(port_), "Server port") - ("message,m", withDefault(message_), "Message to send"); + ("help,h", "Show help") + ("host,H", withDefault(host_, ""), "Server host (IP or DNS)") + ("port,p", withDefault(port_, ""), "Server port") + ("message,m", withDefault(message_, ""), "Message to send"); // clang-format on } std::string EchoClientCli::getHost() const { - return vm_["host"].as(); + return vm_.at("host").as(); } - int EchoClientCli::getPort() const { - return vm_["port"].as(); + return vm_.at("port").as(); } - std::string EchoClientCli::getMessage() const { - return vm_["message"].as(); + return vm_.at("message").as(); } diff --git a/src/client/echo_client_cli.hpp b/src/client/echo_client_cli.hpp index 7dfc133..2f818d2 100644 --- a/src/client/echo_client_cli.hpp +++ b/src/client/echo_client_cli.hpp @@ -4,7 +4,7 @@ #include "option_utils.hpp" #include -class EchoClientCli : public CliBase, public OptionUtils +class EchoClientCli : public CliBase, protected OptionUtils { public: EchoClientCli(); @@ -17,6 +17,7 @@ class EchoClientCli : public CliBase, public OptionUtils void setupOptions() override; private: + // defaults (used only to show defaults in help via withDefault) std::string host_; int port_; std::string message_; diff --git a/src/common/option_utils.hpp b/src/common/option_utils.hpp index 2f8bbc1..a907ef2 100644 --- a/src/common/option_utils.hpp +++ b/src/common/option_utils.hpp @@ -4,11 +4,17 @@ class OptionUtils { + public: + template + using OptionValue = boost::program_options::typed_value *; + + template + static OptionValue + withDefault(const T &value, const char *name = nullptr); + protected: OptionUtils() = default; ~OptionUtils() = default; - - template static auto withDefault(T value); }; #include "option_utils.tpp" diff --git a/src/common/option_utils.tpp b/src/common/option_utils.tpp index 7788a96..4ce5df9 100644 --- a/src/common/option_utils.tpp +++ b/src/common/option_utils.tpp @@ -1,8 +1,13 @@ #pragma once - #include "option_utils.hpp" -template auto OptionUtils::withDefault(T value) +template +OptionUtils::OptionValue +OptionUtils::withDefault(const T &value, const char *name) { - return boost::program_options::value()->default_value(value); + auto v = boost::program_options::value()->default_value(value); + if (name) { + v->value_name(name); // Optional + } + return v; } diff --git a/src/common/server.hpp b/src/common/server.hpp deleted file mode 100644 index 60a60a1..0000000 --- a/src/common/server.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -class Server -{ - public: - virtual ~Server() = default; - virtual void start() = 0; - virtual void stop() = 0; -}; diff --git a/src/server/echo_server_cli.cpp b/src/server/echo_server_cli.cpp index 60a4c72..a2c6a57 100644 --- a/src/server/echo_server_cli.cpp +++ b/src/server/echo_server_cli.cpp @@ -11,18 +11,17 @@ void EchoServerCli::setupOptions() { // clang-format off desc_.add_options() - ("help,h", "Show help") - ("port,p", withDefault(port_), "Port to listen on") - ("address,a", withDefault(address_), "Bind address (e.g. 0.0.0.0 or 127.0.0.1)"); + ("help,h", "Show help") + ("port,p", withDefault(port_, ""), "Port to listen on") + ("address,a", withDefault(address_, "
"), "Bind address (e.g. 0.0.0.0)"); // clang-format on } int EchoServerCli::getPort() const { - return vm_["port"].as(); + return vm_.at("port").as(); } - std::string EchoServerCli::getAddress() const { - return vm_["address"].as(); + return vm_.at("address").as(); } diff --git a/src/server/echo_server_cli.hpp b/src/server/echo_server_cli.hpp index 0064394..817f7c8 100644 --- a/src/server/echo_server_cli.hpp +++ b/src/server/echo_server_cli.hpp @@ -4,7 +4,7 @@ #include "option_utils.hpp" #include -class EchoServerCli : public CliBase, public OptionUtils +class EchoServerCli : public CliBase, protected OptionUtils { public: EchoServerCli();