mirror of
https://github.com/transmission/transmission.git
synced 2026-02-15 07:26:49 +00:00
refactor: add helpers to avoid code duplication (#8101)
* refactor: add helpers to avoid code duplication * refactor: remove unused default_value arg
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
@@ -38,7 +39,62 @@ namespace libtransmission::serializer
|
||||
namespace
|
||||
{
|
||||
template<typename T, size_t N>
|
||||
using Lookup = std::array<std::pair<std::string_view, T>, N>;
|
||||
using LookupTable = std::array<std::pair<std::string_view, T>, N>;
|
||||
|
||||
template<typename T, size_t N>
|
||||
[[nodiscard]] tr_variant from_enum_or_integral_with_lookup(LookupTable<T, N> const& rows, T const src)
|
||||
{
|
||||
static_assert(std::is_enum_v<T> || std::is_integral_v<T>);
|
||||
|
||||
for (auto const& [key, value] : rows)
|
||||
{
|
||||
if (value == src)
|
||||
{
|
||||
return tr_variant::unmanaged_string(key);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int64_t>(src);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
[[nodiscard]] bool to_enum_or_integral_with_lookup(LookupTable<T, N> const& rows, tr_variant const& src, T* tgt)
|
||||
{
|
||||
static_assert(std::is_enum_v<T> || std::is_integral_v<T>);
|
||||
|
||||
if (tgt == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<std::string_view>())
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [key, value] : rows)
|
||||
{
|
||||
if (key == needle)
|
||||
{
|
||||
*tgt = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<int64_t>())
|
||||
{
|
||||
for (auto const& [key, value] : rows)
|
||||
{
|
||||
if (static_cast<int64_t>(value) == *val)
|
||||
{
|
||||
*tgt = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
@@ -96,7 +152,7 @@ tr_variant from_int64(int64_t const& val)
|
||||
|
||||
// ---
|
||||
|
||||
auto constexpr EncryptionKeys = Lookup<tr_encryption_mode, 3U>{ {
|
||||
auto constexpr EncryptionKeys = LookupTable<tr_encryption_mode, 3U>{ {
|
||||
{ "required", TR_ENCRYPTION_REQUIRED },
|
||||
{ "preferred", TR_ENCRYPTION_PREFERRED },
|
||||
{ "allowed", TR_CLEAR_PREFERRED },
|
||||
@@ -104,55 +160,17 @@ auto constexpr EncryptionKeys = Lookup<tr_encryption_mode, 3U>{ {
|
||||
|
||||
bool to_encryption_mode(tr_variant const& src, tr_encryption_mode* tgt)
|
||||
{
|
||||
static constexpr auto& Keys = EncryptionKeys;
|
||||
|
||||
if (auto const val = src.value_if<std::string_view>())
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [key, encryption] : Keys)
|
||||
{
|
||||
if (key == needle)
|
||||
{
|
||||
*tgt = encryption;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<int64_t>())
|
||||
{
|
||||
for (auto const& [key, encryption] : Keys)
|
||||
{
|
||||
if (encryption == *val)
|
||||
{
|
||||
*tgt = encryption;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return to_enum_or_integral_with_lookup(EncryptionKeys, src, tgt);
|
||||
}
|
||||
|
||||
tr_variant from_encryption_mode(tr_encryption_mode const& val)
|
||||
{
|
||||
static constexpr auto& Keys = EncryptionKeys;
|
||||
|
||||
for (auto const& [key, encryption] : Keys)
|
||||
{
|
||||
if (encryption == val)
|
||||
{
|
||||
return tr_variant::unmanaged_string(key);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int64_t>(val);
|
||||
return from_enum_or_integral_with_lookup(EncryptionKeys, val);
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
auto constexpr LogKeys = Lookup<tr_log_level, 7U>{ {
|
||||
auto constexpr LogKeys = LookupTable<tr_log_level, 7U>{ {
|
||||
{ "critical", TR_LOG_CRITICAL },
|
||||
{ "debug", TR_LOG_DEBUG },
|
||||
{ "error", TR_LOG_ERROR },
|
||||
@@ -164,35 +182,7 @@ auto constexpr LogKeys = Lookup<tr_log_level, 7U>{ {
|
||||
|
||||
bool to_log_level(tr_variant const& src, tr_log_level* tgt)
|
||||
{
|
||||
static constexpr auto& Keys = LogKeys;
|
||||
|
||||
if (auto const val = src.value_if<std::string_view>())
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [name, log_level] : Keys)
|
||||
{
|
||||
if (needle == name)
|
||||
{
|
||||
*tgt = log_level;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<int64_t>())
|
||||
{
|
||||
for (auto const& [name, log_level] : Keys)
|
||||
{
|
||||
if (log_level == *val)
|
||||
{
|
||||
*tgt = log_level;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return to_enum_or_integral_with_lookup(LogKeys, src, tgt);
|
||||
}
|
||||
|
||||
tr_variant from_log_level(tr_log_level const& val)
|
||||
@@ -265,7 +255,7 @@ tr_variant from_port(tr_port const& val)
|
||||
|
||||
// ---
|
||||
|
||||
auto constexpr PreallocationKeys = Lookup<tr_open_files::Preallocation, 5U>{ {
|
||||
auto constexpr PreallocationKeys = LookupTable<tr_open_files::Preallocation, 5U>{ {
|
||||
{ "off", tr_open_files::Preallocation::None },
|
||||
{ "none", tr_open_files::Preallocation::None },
|
||||
{ "fast", tr_open_files::Preallocation::Sparse },
|
||||
@@ -275,35 +265,7 @@ auto constexpr PreallocationKeys = Lookup<tr_open_files::Preallocation, 5U>{ {
|
||||
|
||||
bool to_preallocation_mode(tr_variant const& src, tr_open_files::Preallocation* tgt)
|
||||
{
|
||||
static constexpr auto& Keys = PreallocationKeys;
|
||||
|
||||
if (auto const val = src.value_if<std::string_view>())
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (name == needle)
|
||||
{
|
||||
*tgt = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<int64_t>())
|
||||
{
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (value == static_cast<tr_open_files::Preallocation>(*val))
|
||||
{
|
||||
*tgt = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return to_enum_or_integral_with_lookup(PreallocationKeys, src, tgt);
|
||||
}
|
||||
|
||||
tr_variant from_preallocation_mode(tr_open_files::Preallocation const& val)
|
||||
@@ -313,7 +275,7 @@ tr_variant from_preallocation_mode(tr_open_files::Preallocation const& val)
|
||||
|
||||
// ---
|
||||
|
||||
auto constexpr PreferredTransportKeys = Lookup<tr_preferred_transport, TR_NUM_PREFERRED_TRANSPORT>{ {
|
||||
auto constexpr PreferredTransportKeys = LookupTable<tr_preferred_transport, TR_NUM_PREFERRED_TRANSPORT>{ {
|
||||
{ "utp", TR_PREFER_UTP },
|
||||
{ "tcp", TR_PREFER_TCP },
|
||||
} };
|
||||
@@ -324,30 +286,8 @@ bool to_preferred_transport(
|
||||
{
|
||||
static auto constexpr LoadSingle = [](tr_variant const& var)
|
||||
{
|
||||
static constexpr auto& Keys = PreferredTransportKeys;
|
||||
|
||||
if (auto const val = var.value_if<std::string_view>())
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (name == needle)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = var.value_if<int64_t>())
|
||||
{
|
||||
if (auto const i = *val; i >= 0 && i < TR_NUM_PREFERRED_TRANSPORT)
|
||||
{
|
||||
return static_cast<tr_preferred_transport>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return TR_NUM_PREFERRED_TRANSPORT;
|
||||
auto tmp = tr_preferred_transport{};
|
||||
return to_enum_or_integral_with_lookup(PreferredTransportKeys, var, &tmp) ? tmp : TR_NUM_PREFERRED_TRANSPORT;
|
||||
};
|
||||
|
||||
if (auto* const l = src.get_if<tr_variant::Vector>(); l != nullptr)
|
||||
@@ -384,15 +324,7 @@ tr_variant from_preferred_transport(small::max_size_vector<tr_preferred_transpor
|
||||
{
|
||||
static auto constexpr SaveSingle = [](tr_preferred_transport const ele) -> tr_variant
|
||||
{
|
||||
for (auto const& [key, value] : PreferredTransportKeys)
|
||||
{
|
||||
if (value == ele)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return ele;
|
||||
return from_enum_or_integral_with_lookup(PreferredTransportKeys, ele);
|
||||
};
|
||||
|
||||
auto ret = tr_variant::Vector{};
|
||||
@@ -464,7 +396,7 @@ tr_variant from_string(std::string const& val)
|
||||
// RFCs 2474, 3246, 4594 & 8622
|
||||
// Service class names are defined in RFC 4594, RFC 5865, and RFC 8622.
|
||||
// Not all platforms have these IPTOS_ definitions, so hardcode them here
|
||||
auto constexpr DiffServKeys = Lookup<int, 28U>{ {
|
||||
auto constexpr DiffServKeys = LookupTable<int, 28U>{ {
|
||||
{ "cs0", 0x00 }, // IPTOS_CLASS_CS0
|
||||
{ "le", 0x04 },
|
||||
{ "cs1", 0x20 }, // IPTOS_CLASS_CS1
|
||||
@@ -500,103 +432,36 @@ auto constexpr DiffServKeys = Lookup<int, 28U>{ {
|
||||
|
||||
bool to_diffserv_t(tr_variant const& src, tr_diffserv_t* tgt)
|
||||
{
|
||||
static constexpr auto& Keys = DiffServKeys;
|
||||
|
||||
if (auto const val = src.value_if<std::string_view>())
|
||||
auto tmp = int{};
|
||||
if (!to_enum_or_integral_with_lookup(DiffServKeys, src, &tmp))
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (name == needle)
|
||||
{
|
||||
*tgt = tr_diffserv_t{ value };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<int64_t>())
|
||||
{
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (value == *val)
|
||||
{
|
||||
*tgt = tr_diffserv_t{ value };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
*tgt = tr_diffserv_t{ tmp };
|
||||
return true;
|
||||
}
|
||||
|
||||
tr_variant from_diffserv_t(tr_diffserv_t const& val)
|
||||
{
|
||||
static constexpr auto& Keys = DiffServKeys;
|
||||
|
||||
for (auto const& [key, value] : Keys)
|
||||
{
|
||||
if (value == val)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int64_t>(val);
|
||||
return from_enum_or_integral_with_lookup(DiffServKeys, static_cast<int>(val));
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
auto constexpr VerifyModeKeys = Lookup<tr_verify_added_mode, 2U>{ {
|
||||
auto constexpr VerifyModeKeys = LookupTable<tr_verify_added_mode, 2U>{ {
|
||||
{ "fast", TR_VERIFY_ADDED_FAST },
|
||||
{ "full", TR_VERIFY_ADDED_FULL },
|
||||
} };
|
||||
|
||||
bool to_verify_added_mode(tr_variant const& src, tr_verify_added_mode* tgt)
|
||||
{
|
||||
static constexpr auto& Keys = VerifyModeKeys;
|
||||
|
||||
if (auto const val = src.value_if<std::string_view>())
|
||||
{
|
||||
auto const needle = tr_strlower(tr_strv_strip(*val));
|
||||
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (name == needle)
|
||||
{
|
||||
*tgt = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const val = src.value_if<int64_t>())
|
||||
{
|
||||
for (auto const& [name, value] : Keys)
|
||||
{
|
||||
if (value == *val)
|
||||
{
|
||||
*tgt = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return to_enum_or_integral_with_lookup(VerifyModeKeys, src, tgt);
|
||||
}
|
||||
|
||||
tr_variant from_verify_added_mode(tr_verify_added_mode const& val)
|
||||
{
|
||||
for (auto const& [key, value] : VerifyModeKeys)
|
||||
{
|
||||
if (value == val)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int64_t>(val);
|
||||
return from_enum_or_integral_with_lookup(VerifyModeKeys, val);
|
||||
}
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
Reference in New Issue
Block a user