// This file Copyright © Mnemosyne LLC. // It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only), // or any future license endorsed by Mnemosyne LLC. // License text can be found in the licenses/ folder. #pragma once #include // size_t #include // int64_t #include #include #include #include #include #include class QByteArray; class Speed; class TorrentHash; struct Peer; struct TorrentFile; struct TrackerStat; namespace trqt::variant_helpers { template>* = nullptr> auto getValue(tr_variant const* variant) { std::optional ret; if (auto value = T{}; tr_variantGetBool(variant, &value)) { ret = value; } return ret; } template< typename T, typename std::enable_if_t< std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v>* = nullptr> auto getValue(tr_variant const* variant) { std::optional ret; if (auto value = int64_t{}; tr_variantGetInt(variant, &value)) { ret = value; } return ret; } template>* = nullptr> auto getValue(tr_variant const* variant) { std::optional ret; if (auto value = T{}; tr_variantGetReal(variant, &value)) { ret = value; } return ret; } template>* = nullptr> auto getValue(tr_variant const* variant) { std::optional ret; if (auto sv = std::string_view{}; tr_variantGetStrView(variant, &sv)) { ret = QString::fromUtf8(std::data(sv), std::size(sv)); } return ret; } template>* = nullptr> auto getValue(tr_variant const* variant) { std::optional ret; if (auto sv = std::string_view{}; tr_variantGetStrView(variant, &sv)) { ret = std::string_view(std::data(sv), std::size(sv)); } return ret; } template< typename C, typename T = typename C::value_type, typename std::enable_if_t< std::is_same_v || std::is_same_v> || std::is_same_v>>* = nullptr> auto getValue(tr_variant const* var) { std::optional ret; if (var != nullptr && var->holds_alternative()) { auto list = C{}; for (size_t i = 0, n = tr_variantListSize(var); i < n; ++i) { tr_variant* const child = tr_variantListChild(const_cast(var), i); auto const value = getValue(child); if (value) { list.push_back(*value); } } ret = list; } return ret; } template bool change(T& setme, T const& value) { bool const changed = setme != value; if (changed) { setme = value; } return changed; } bool change(double& setme, double const& value); bool change(Speed& setme, tr_variant const* value); bool change(Peer& setme, tr_variant const* value); bool change(TorrentFile& setme, tr_variant const* value); bool change(TorrentHash& setme, tr_variant const* value); bool change(TrackerStat& setme, tr_variant const* value); template bool change(T& setme, tr_variant const* variant) { auto const value = getValue(variant); return value && change(setme, *value); } template bool change(std::vector& setme, tr_variant const* value) { bool changed = false; auto const n = tr_variantListSize(value); if (setme.size() != n) { setme.resize(n); changed = true; } for (size_t i = 0; i < n; ++i) { changed = change(setme[i], tr_variantListChild(const_cast(value), i)) || changed; } return changed; } /// template auto dictFind(tr_variant* dict, tr_quark key) { std::optional ret; if (auto const* child = tr_variantDictFind(dict, key); child != nullptr) { ret = getValue(child); } return ret; } /// void variantInit(tr_variant* init_me, bool value); void variantInit(tr_variant* init_me, int64_t value); void variantInit(tr_variant* init_me, int value); void variantInit(tr_variant* init_me, double value); void variantInit(tr_variant* init_me, QByteArray const& value); void variantInit(tr_variant* init_me, QString const& value); void variantInit(tr_variant* init_me, std::string_view value); void variantInit(tr_variant* init_me, char const* value) = delete; // use string_view template void variantInit(tr_variant* init_me, C const& value) { tr_variantInitList(init_me, std::size(value)); for (auto const& item : value) { variantInit(tr_variantListAdd(init_me), item); } } template void listAdd(tr_variant* list, T const& value) { variantInit(tr_variantListAdd(list), value); } template void dictAdd(tr_variant* dict, tr_quark key, T const& value) { variantInit(tr_variantDictAdd(dict, key), value); } } // namespace trqt::variant_helpers