From 8d25484cdbc131f2a47db704b82ef9a8ec98cea7 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Thu, 13 Nov 2025 03:04:55 +0800 Subject: [PATCH] refactor: use new `tr_variant` API in daemon (#7103) --- daemon/daemon.cc | 136 +++++++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 63 deletions(-) diff --git a/daemon/daemon.cc b/daemon/daemon.cc index cf8b266f4..70e31aef7 100644 --- a/daemon/daemon.cc +++ b/daemon/daemon.cc @@ -392,13 +392,14 @@ tr_rpc_callback_status on_rpc_callback(tr_session* /*session*/, tr_rpc_callback_ tr_variant load_settings(char const* config_dir) { - auto app_defaults = tr_variant::make_map(); - tr_variantDictAddStrView(&app_defaults, TR_KEY_watch_dir, ""sv); - tr_variantDictAddBool(&app_defaults, TR_KEY_watch_dir_enabled, false); - tr_variantDictAddBool(&app_defaults, TR_KEY_watch_dir_force_generic, false); - tr_variantDictAddBool(&app_defaults, TR_KEY_rpc_enabled, true); - tr_variantDictAddBool(&app_defaults, TR_KEY_start_paused, false); - tr_variantDictAddStrView(&app_defaults, TR_KEY_pidfile, ""sv); + auto app_defaults_map = tr_variant::Map{ 6U }; + app_defaults_map.try_emplace(TR_KEY_watch_dir, tr_variant::unmanaged_string(""sv)); + app_defaults_map.try_emplace(TR_KEY_watch_dir_enabled, false); + app_defaults_map.try_emplace(TR_KEY_watch_dir_force_generic, false); + app_defaults_map.try_emplace(TR_KEY_rpc_enabled, true); + app_defaults_map.try_emplace(TR_KEY_start_paused, false); + app_defaults_map.try_emplace(TR_KEY_pidfile, tr_variant::unmanaged_string(""sv)); + auto const app_defaults = tr_variant{ std::move(app_defaults_map) }; return tr_sessionLoadSettings(&app_defaults, config_dir, MyName); } @@ -460,6 +461,12 @@ bool tr_daemon::parse_args(int argc, char const* const* argv, bool* dump_setting *dump_settings = false; *foreground = false; + auto* const map = settings_.get_if(); + if (map == nullptr) + { + return false; + } + tr_optind = 1; while ((c = tr_getopt(Usage, argc, argv, std::data(Options), &optstr)) != TR_OPT_DONE) @@ -467,46 +474,46 @@ bool tr_daemon::parse_args(int argc, char const* const* argv, bool* dump_setting switch (c) { case 'a': - tr_variantDictAddStr(&settings_, TR_KEY_rpc_whitelist, optstr); - tr_variantDictAddBool(&settings_, TR_KEY_rpc_whitelist_enabled, true); + map->insert_or_assign(TR_KEY_rpc_whitelist, optstr); + map->insert_or_assign(TR_KEY_rpc_whitelist_enabled, true); break; case 'b': - tr_variantDictAddBool(&settings_, TR_KEY_blocklist_enabled, true); + map->insert_or_assign(TR_KEY_blocklist_enabled, true); break; case 'B': - tr_variantDictAddBool(&settings_, TR_KEY_blocklist_enabled, false); + map->insert_or_assign(TR_KEY_blocklist_enabled, false); break; case 'c': - tr_variantDictAddStr(&settings_, TR_KEY_watch_dir, optstr); - tr_variantDictAddBool(&settings_, TR_KEY_watch_dir_enabled, true); + map->insert_or_assign(TR_KEY_watch_dir, optstr); + map->insert_or_assign(TR_KEY_watch_dir_enabled, true); break; case 'C': - tr_variantDictAddBool(&settings_, TR_KEY_watch_dir_enabled, false); + map->insert_or_assign(TR_KEY_watch_dir_enabled, false); break; case 941: - tr_variantDictAddStr(&settings_, TR_KEY_incomplete_dir, optstr); - tr_variantDictAddBool(&settings_, TR_KEY_incomplete_dir_enabled, true); + map->insert_or_assign(TR_KEY_incomplete_dir, optstr); + map->insert_or_assign(TR_KEY_incomplete_dir_enabled, true); break; case 942: - tr_variantDictAddBool(&settings_, TR_KEY_incomplete_dir_enabled, false); + map->insert_or_assign(TR_KEY_incomplete_dir_enabled, false); break; case 943: - tr_variantDictAddStr(&settings_, TR_KEY_default_trackers, optstr); + map->insert_or_assign(TR_KEY_default_trackers, optstr); break; case 994: - tr_variantDictAddBool(&settings_, TR_KEY_sequential_download, true); + map->insert_or_assign(TR_KEY_sequential_download, true); break; case 995: - tr_variantDictAddBool(&settings_, TR_KEY_sequential_download, false); + map->insert_or_assign(TR_KEY_sequential_download, false); break; case 'd': @@ -534,125 +541,125 @@ bool tr_daemon::parse_args(int argc, char const* const* argv, bool* dump_setting return false; case 'o': - tr_variantDictAddBool(&settings_, TR_KEY_dht_enabled, true); + map->insert_or_assign(TR_KEY_dht_enabled, true); break; case 'O': - tr_variantDictAddBool(&settings_, TR_KEY_dht_enabled, false); + map->insert_or_assign(TR_KEY_dht_enabled, false); break; case 'p': if (auto const rpc_port = tr_num_parse(optstr); rpc_port) { - tr_variantDictAddInt(&settings_, TR_KEY_rpc_port, *rpc_port); + map->insert_or_assign(TR_KEY_rpc_port, *rpc_port); } break; case 't': - tr_variantDictAddBool(&settings_, TR_KEY_rpc_authentication_required, true); + map->insert_or_assign(TR_KEY_rpc_authentication_required, true); break; case 'T': - tr_variantDictAddBool(&settings_, TR_KEY_rpc_authentication_required, false); + map->insert_or_assign(TR_KEY_rpc_authentication_required, false); break; case 'u': - tr_variantDictAddStr(&settings_, TR_KEY_rpc_username, optstr); + map->insert_or_assign(TR_KEY_rpc_username, optstr); break; case 'v': - tr_variantDictAddStr(&settings_, TR_KEY_rpc_password, optstr); + map->insert_or_assign(TR_KEY_rpc_password, optstr); break; case 'w': - tr_variantDictAddStr(&settings_, TR_KEY_download_dir, optstr); + map->insert_or_assign(TR_KEY_download_dir, optstr); break; case 'P': if (auto const peer_port = tr_num_parse(optstr); peer_port) { - tr_variantDictAddInt(&settings_, TR_KEY_peer_port, *peer_port); + map->insert_or_assign(TR_KEY_peer_port, *peer_port); } break; case 'm': - tr_variantDictAddBool(&settings_, TR_KEY_port_forwarding_enabled, true); + map->insert_or_assign(TR_KEY_port_forwarding_enabled, true); break; case 'M': - tr_variantDictAddBool(&settings_, TR_KEY_port_forwarding_enabled, false); + map->insert_or_assign(TR_KEY_port_forwarding_enabled, false); break; case 'L': if (auto const peer_limit_global = tr_num_parse(optstr); peer_limit_global && *peer_limit_global >= 0) { - tr_variantDictAddInt(&settings_, TR_KEY_peer_limit_global, *peer_limit_global); + map->insert_or_assign(TR_KEY_peer_limit_global, *peer_limit_global); } break; case 'l': if (auto const peer_limit_tor = tr_num_parse(optstr); peer_limit_tor && *peer_limit_tor >= 0) { - tr_variantDictAddInt(&settings_, TR_KEY_peer_limit_per_torrent, *peer_limit_tor); + map->insert_or_assign(TR_KEY_peer_limit_per_torrent, *peer_limit_tor); } break; case 800: - tr_variantDictAddBool(&settings_, TR_KEY_start_paused, true); + map->insert_or_assign(TR_KEY_start_paused, true); break; case 910: - tr_variantDictAddInt(&settings_, TR_KEY_encryption, TR_ENCRYPTION_REQUIRED); + map->insert_or_assign(TR_KEY_encryption, TR_ENCRYPTION_REQUIRED); break; case 911: - tr_variantDictAddInt(&settings_, TR_KEY_encryption, TR_ENCRYPTION_PREFERRED); + map->insert_or_assign(TR_KEY_encryption, TR_ENCRYPTION_PREFERRED); break; case 912: - tr_variantDictAddInt(&settings_, TR_KEY_encryption, TR_CLEAR_PREFERRED); + map->insert_or_assign(TR_KEY_encryption, TR_CLEAR_PREFERRED); break; case 'i': - tr_variantDictAddStr(&settings_, TR_KEY_bind_address_ipv4, optstr); + map->insert_or_assign(TR_KEY_bind_address_ipv4, optstr); break; case 'I': - tr_variantDictAddStr(&settings_, TR_KEY_bind_address_ipv6, optstr); + map->insert_or_assign(TR_KEY_bind_address_ipv6, optstr); break; case 'r': - tr_variantDictAddStr(&settings_, TR_KEY_rpc_bind_address, optstr); + map->insert_or_assign(TR_KEY_rpc_bind_address, optstr); break; case 953: if (auto const ratio_limit = tr_num_parse(optstr); ratio_limit) { - tr_variantDictAddReal(&settings_, TR_KEY_ratio_limit, *ratio_limit); + map->insert_or_assign(TR_KEY_ratio_limit, *ratio_limit); } - tr_variantDictAddBool(&settings_, TR_KEY_ratio_limit_enabled, true); + map->insert_or_assign(TR_KEY_ratio_limit_enabled, true); break; case 954: - tr_variantDictAddBool(&settings_, TR_KEY_ratio_limit_enabled, false); + map->insert_or_assign(TR_KEY_ratio_limit_enabled, false); break; case 'x': - tr_variantDictAddStr(&settings_, TR_KEY_pidfile, optstr); + map->insert_or_assign(TR_KEY_pidfile, optstr); break; case 'y': - tr_variantDictAddBool(&settings_, TR_KEY_lpd_enabled, true); + map->insert_or_assign(TR_KEY_lpd_enabled, true); break; case 'Y': - tr_variantDictAddBool(&settings_, TR_KEY_lpd_enabled, false); + map->insert_or_assign(TR_KEY_lpd_enabled, false); break; case 810: if (auto const level = tr_logGetLevelFromKey(optstr); level) { - tr_variantDictAddInt(&settings_, TR_KEY_message_level, *level); + map->insert_or_assign(TR_KEY_message_level, *level); } else { @@ -663,25 +670,25 @@ bool tr_daemon::parse_args(int argc, char const* const* argv, bool* dump_setting case 811: std::cerr << "WARN: --log-error is deprecated. Use --log-level=error" << std::endl; - tr_variantDictAddInt(&settings_, TR_KEY_message_level, TR_LOG_ERROR); + map->insert_or_assign(TR_KEY_message_level, TR_LOG_ERROR); break; case 812: std::cerr << "WARN: --log-info is deprecated. Use --log-level=info" << std::endl; - tr_variantDictAddInt(&settings_, TR_KEY_message_level, TR_LOG_INFO); + map->insert_or_assign(TR_KEY_message_level, TR_LOG_INFO); break; case 813: std::cerr << "WARN: --log-debug is deprecated. Use --log-level=debug" << std::endl; - tr_variantDictAddInt(&settings_, TR_KEY_message_level, TR_LOG_DEBUG); + map->insert_or_assign(TR_KEY_message_level, TR_LOG_DEBUG); break; case 830: - tr_variantDictAddBool(&settings_, TR_KEY_utp_enabled, true); + map->insert_or_assign(TR_KEY_utp_enabled, true); break; case 831: - tr_variantDictAddBool(&settings_, TR_KEY_utp_enabled, false); + map->insert_or_assign(TR_KEY_utp_enabled, false); break; case TR_OPT_UNK: @@ -778,9 +785,15 @@ int tr_daemon::start([[maybe_unused]] bool foreground) tr_logAddInfo(fmt::format(fmt::runtime(_("Loading settings from '{path}'")), fmt::arg("path", cdir))); tr_sessionSaveSettings(session, cdir, settings_); - auto sv = std::string_view{}; - (void)tr_variantDictFindStrView(&settings_, TR_KEY_pidfile, &sv); - auto const sz_pid_filename = std::string{ sv }; + auto const* const settings_map = settings_.get_if(); + if (settings_map == nullptr) + { + static auto constexpr Errmsg = "Unreachable code, please file a bug report"sv; + printMessage(log_stream_, TR_LOG_ERROR, MyName, Errmsg, __FILE__, __LINE__); + return 1; + } + + auto const sz_pid_filename = std::string{ settings_map->value_if(TR_KEY_pidfile).value_or(""sv) }; auto pidfile_created = false; if (!std::empty(sz_pid_filename)) { @@ -809,7 +822,7 @@ int tr_daemon::start([[maybe_unused]] bool foreground) } } - if (auto tmp_bool = false; tr_variantDictFindBool(&settings_, TR_KEY_rpc_authentication_required, &tmp_bool) && tmp_bool) + if (settings_map->value_if(TR_KEY_rpc_authentication_required).value_or(false)) { tr_logAddInfo(_("Requiring authentication")); } @@ -824,14 +837,11 @@ int tr_daemon::start([[maybe_unused]] bool foreground) /* maybe add a watchdir */ auto watchdir = std::unique_ptr{}; - if (auto tmp_bool = false; tr_variantDictFindBool(&settings_, TR_KEY_watch_dir_enabled, &tmp_bool) && tmp_bool) + if (settings_map->value_if(TR_KEY_watch_dir_enabled).value_or(false)) { - auto force_generic = false; - (void)tr_variantDictFindBool(&settings_, TR_KEY_watch_dir_force_generic, &force_generic); + auto const force_generic = settings_map->value_if(TR_KEY_watch_dir_force_generic).value_or(false); - auto dir = std::string_view{}; - (void)tr_variantDictFindStrView(&settings_, TR_KEY_watch_dir, &dir); - if (!std::empty(dir)) + if (auto dir = settings_map->value_if(TR_KEY_watch_dir).value_or(""sv); !std::empty(dir)) { tr_logAddInfo(fmt::format(fmt::runtime(_("Watching '{path}' for new torrent files")), fmt::arg("path", dir))); @@ -850,7 +860,7 @@ int tr_daemon::start([[maybe_unused]] bool foreground) { tr_ctor* ctor = tr_ctorNew(my_session_); - if (auto paused = false; tr_variantDictFindBool(&settings_, TR_KEY_start_paused, &paused) && paused) + if (settings_map->value_if(TR_KEY_start_paused).value_or(false)) { tr_ctorSetPaused(ctor, TR_FORCE, true); }