5#ifndef QXMPPIQHANDLING_H
6#define QXMPPIQHANDLING_H
8#include "QXmppAsync_p.h"
9#include "QXmppClient.h"
10#include "QXmppE2eeMetadata.h"
12#include "QXmppUtils_p.h"
13#include "QXmppXmlTags_p.h"
15#include "StringLiterals.h"
24 const QString &requestId,
25 const QString &requestFrom,
26 const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
29QXMPP_EXPORT std::tuple<bool, QString, QString> checkIsIqRequest(
const QDomElement &el);
31template<
typename... VariantTypes>
33 const QString &requestId,
34 const QString &requestFrom,
35 const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
36 std::variant<VariantTypes...> &&result)
39 [&]<
typename T>(T &&value) {
41 std::is_base_of_v<QXmppIq, T> || std::is_same_v<QXmppStanza::Error, T> || IsTask<T>,
42 "QXmppIq based type, QXmppStanza::Error or QXmppTask required");
44 if constexpr (std::is_base_of_v<QXmppIq, T>) {
45 sendIqReply(client, requestId, requestFrom, e2eeMetadata, std::move(value));
46 }
else if constexpr (std::is_same_v<QXmppStanza::Error, T>) {
50 sendIqReply(client, requestId, requestFrom, e2eeMetadata, std::move(iq));
51 }
else if constexpr (IsTask<T>) {
52 value.then(client, [=](TaskValueType<T> &&v) {
53 processHandleIqResult(client, requestId, requestFrom, e2eeMetadata, std::move(v));
62 const QString &requestId,
63 const QString &requestFrom,
64 const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
67 task.
then(client, [client, requestId, requestFrom, e2eeMetadata](T result) {
68 processHandleIqResult(client, requestId, requestFrom, e2eeMetadata, result);
72template<
typename T,
typename = std::enable_if_t<std::is_base_of_v<QXmppIq, T>,
void>>
74 const QString &requestId,
75 const QString &requestFrom,
76 const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
79 sendIqReply(client, requestId, requestFrom, e2eeMetadata, std::move(result));
82template<
typename Handler,
typename IqType>
83auto invokeIqHandler(Handler handler, IqType &&iq)
85 if constexpr (std::is_invocable<Handler, IqType &&>()) {
86 return handler(std::move(iq));
88 return handler->handleIq(std::move(iq));
92template<
typename IqType,
typename Handler>
93bool handleIqType(Handler handler,
95 const QDomElement &element,
96 const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
97 const QString &tagName,
98 const QString &xmlNamespace)
100 if (isPayloadType<IqType>(std::tuple { tagName, xmlNamespace })) {
101 if (
auto iq = parseElement<IqType>(element)) {
102 if constexpr (std::is_base_of_v<QXmppIq, IqType>) {
106 processHandleIqResult(client, element.attribute(u
"id"_s), element.attribute(u
"from"_s), e2eeMetadata,
107 invokeIqHandler(std::forward<Handler>(handler), std::move(*iq)));
192template<
typename... IqTypes,
typename Handler>
194 const std::optional<QXmppE2eeMetadata> &e2eeMetadata,
198 if (
auto [isRequest, tagName, xmlns] = Private::checkIsIqRequest(element); isRequest) {
199 return (Private::handleIqType<IqTypes>(handler, client, element, e2eeMetadata, tagName, xmlns) || ...);
275template<
typename... IqTypes,
typename Handler>
278 return handleIqRequests<IqTypes...>(element, std::nullopt, client, std::forward<Handler>(handler));
Main class for starting and managing connections to XMPP servers.
Definition QXmppClient.h:62
The QXmppIq class is the base class for all IQs.
Definition QXmppIq.h:23
void setType(QXmppIq::Type)
Definition QXmppIq.cpp:70
The Error class represents a stanza error.
Definition QXmppStanza.h:112
void setError(const QXmppStanza::Error &error)
Definition QXmppStanza.cpp:811
void setE2eeMetadata(const std::optional< QXmppE2eeMetadata > &e2eeMetadata)
Definition QXmppStanza.cpp:888
Definition QXmppTask.h:330
auto then(const QObject *context, Continuation continuation) -> QXmppTask< QXmpp::Private::InvokeContinuationResult< Continuation, T > >
Definition QXmppTask.h:453
Definition Algorithms.h:14
bool handleIqRequests(const QDomElement &element, const std::optional< QXmppE2eeMetadata > &e2eeMetadata, QXmppClient *client, Handler handler)
Definition QXmppIqHandling.h:193