/* * Copyright (C) 2008-2021 The QXmpp developers * * Author: * Linus Jahn * * Source: * https://github.com/qxmpp-project/qxmpp * * This file is a part of QXmpp library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * */ #ifndef QXMPPFUTUREUTILS_P_H #define QXMPPFUTUREUTILS_P_H // // W A R N I N G // ------------- // // This file is not part of the QXmpp API. This header file may change from // version to version without notice, or even be removed. // // We mean it. // #include #include #include #include #include namespace QXmpp::Private { // helper for std::visit template struct overloaded : Ts... { using Ts::operator()...; }; // explicit deduction guide (not needed as of C++20) template overloaded(Ts...) -> overloaded; template QFuture makeReadyFuture(T &&value) { QFutureInterface interface(QFutureInterfaceBase::Started); interface.reportResult(value); interface.reportFinished(); return interface.future(); } template QFuture chain(QFuture &&source, QObject *context, Converter task) { auto resultInterface = std::make_shared>(QFutureInterfaceBase::Started); auto *watcher = new QFutureWatcher(context); QObject::connect(watcher, &QFutureWatcherBase::finished, context, [=]() { resultInterface->reportResult(task(watcher->result())); resultInterface->reportFinished(); watcher->deleteLater(); }); watcher->setFuture(source); return resultInterface->future(); } template Result parseIq(Input &&sendResult, Converter convert) { return std::visit(overloaded { [convert { std::move(convert) }](const QDomElement &element) -> Result { IqType iq; iq.parse(element); if (iq.type() == QXmppIq::Error) { return iq.error(); } return convert(std::move(iq)); }, [](QXmpp::PacketState) -> Result { using Error = QXmppStanza::Error; return Error(Error::Wait, Error::UndefinedCondition, QStringLiteral("Couldn't send request: lost connection.")); }, }, sendResult); } template Result parseIq(Input &&sendResult) { return parseIq(std::move(sendResult), [](IqType &&iq) { // no conversion return iq; }); } template QFuture chainIq(QFuture &&input, QObject *context, Converter convert) { return chain(std::move(input), context, [convert { std::move(convert) }](Input &&input) -> Result { return parseIq(std::move(input), convert); }); } template QFuture chainIq(QFuture &&input, QObject *context) { return chain(std::move(input), context, [](Input &&sendResult) { return parseIq(sendResult); }); } } #endif // QXMPPFUTUREUTILS_P_H