Loading...
Searching...
No Matches
QXmppIqHandling.h
// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
#ifndef QXMPPIQHANDLING_H
#define QXMPPIQHANDLING_H
#include "QXmppAsync_p.h"
#include "QXmppClient.h"
#include "QXmppE2eeMetadata.h"
#include "QXmppIq.h"
#include "QXmppUtils_p.h"
#include "QXmppXmlTags_p.h"
#include "StringLiterals.h"
#include <QDomElement>
namespace QXmpp {
namespace Private {
QXMPP_EXPORT void sendIqReply(QXmppClient *client,
const QString &requestId,
const QString &requestFrom,
const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
QXmppIq &&iq);
QXMPP_EXPORT std::tuple<bool, QString, QString> checkIsIqRequest(const QDomElement &el);
template<typename... VariantTypes>
void processHandleIqResult(QXmppClient *client,
const QString &requestId,
const QString &requestFrom,
const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
std::variant<VariantTypes...> &&result)
{
std::visit(
[&]<typename T>(T &&value) {
static_assert(
std::is_base_of_v<QXmppIq, T> || std::is_same_v<QXmppStanza::Error, T> || IsTask<T>,
"QXmppIq based type, QXmppStanza::Error or QXmppTask required");
if constexpr (std::is_base_of_v<QXmppIq, T>) {
sendIqReply(client, requestId, requestFrom, e2eeMetadata, std::move(value));
} else if constexpr (std::is_same_v<QXmppStanza::Error, T>) {
QXmppIq iq;
iq.setType(QXmppIq::Error);
iq.setError(value);
sendIqReply(client, requestId, requestFrom, e2eeMetadata, std::move(iq));
} else if constexpr (IsTask<T>) {
value.then(client, [=](TaskValueType<T> &&v) {
processHandleIqResult(client, requestId, requestFrom, e2eeMetadata, std::move(v));
});
}
},
std::move(result));
}
template<typename T>
void processHandleIqResult(QXmppClient *client,
const QString &requestId,
const QString &requestFrom,
const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
QXmppTask<T> task)
{
task.then(client, [client, requestId, requestFrom, e2eeMetadata](T result) {
processHandleIqResult(client, requestId, requestFrom, e2eeMetadata, result);
});
}
template<typename T, typename = std::enable_if_t<std::is_base_of_v<QXmppIq, T>, void>>
void processHandleIqResult(QXmppClient *client,
const QString &requestId,
const QString &requestFrom,
const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
T &&result)
{
sendIqReply(client, requestId, requestFrom, e2eeMetadata, std::move(result));
}
template<typename Handler, typename IqType>
auto invokeIqHandler(Handler handler, IqType &&iq)
{
if constexpr (std::is_invocable<Handler, IqType &&>()) {
return handler(std::move(iq));
} else {
return handler->handleIq(std::move(iq));
}
}
template<typename IqType, typename Handler>
bool handleIqType(Handler handler,
QXmppClient *client,
const QDomElement &element,
const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
const QString &tagName,
const QString &xmlNamespace)
{
if (isPayloadType<IqType>(std::tuple { tagName, xmlNamespace })) {
if (auto iq = parseElement<IqType>(element)) {
if constexpr (std::is_base_of_v<QXmppIq, IqType>) {
iq->setE2eeMetadata(e2eeMetadata);
}
processHandleIqResult(client, element.attribute(u"id"_s), element.attribute(u"from"_s), e2eeMetadata,
invokeIqHandler(std::forward<Handler>(handler), std::move(*iq)));
return true;
}
}
return false;
}
} // namespace Private
template<typename... IqTypes, typename Handler>
bool handleIqRequests(const QDomElement &element,
const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
QXmppClient *client,
Handler handler)
{
if (auto [isRequest, tagName, xmlns] = Private::checkIsIqRequest(element); isRequest) {
return (Private::handleIqType<IqTypes>(handler, client, element, e2eeMetadata, tagName, xmlns) || ...);
}
return false;
}
template<typename... IqTypes, typename Handler>
bool handleIqRequests(const QDomElement &element, QXmppClient *client, Handler handler)
{
return handleIqRequests<IqTypes...>(element, std::nullopt, client, std::forward<Handler>(handler));
}
} // namespace QXmpp
#endif // QXMPPIQHANDLING_H
QXmppClient
Main class for starting and managing connections to XMPP servers.
Definition QXmppClient.h:62
QXmppIq::Error
@ Error
Error response.
Definition QXmppIq.h:27
QXmppIq::setType
void setType(QXmppIq::Type)
Definition QXmppIq.cpp:70
QXmppStanza::setError
void setError(const QXmppStanza::Error &error)
Definition QXmppStanza.cpp:811
QXmppStanza::setE2eeMetadata
void setE2eeMetadata(const std::optional< QXmppE2eeMetadata > &e2eeMetadata)
Definition QXmppStanza.cpp:888
QXmppTask::then
void then(const QObject *context, Continuation continuation)
Definition QXmppTask.h:89
QXmpp
Definition Algorithms.h:14
QXmpp::handleIqRequests
bool handleIqRequests(const QDomElement &element, const std::optional< QXmppE2eeMetadata > &e2eeMetadata, QXmppClient *client, Handler handler)
Definition QXmppIqHandling.h:193
QXmpp::TaskValueType
typename Private::IsTaskHelper< T >::Type TaskValueType
Definition QXmppTask.h:251