10#include "QXmppStanza.h"
11#include "QXmppVisitHelper_p.h"
13#include "StringLiterals.h"
20namespace QXmpp::Private {
30struct Enums::Data<IqType> {
32 static constexpr auto Values = makeValues<IqType>({
40template<IqType,
typename Payload =
void>
43template<
typename Payload =
void>
44using GetIq = Iq<IqType::Get, Payload>;
46template<
typename Payload =
void>
47using SetIq = Iq<IqType::Set, Payload>;
49template<
typename Payload =
void>
50using ResultIq = Iq<IqType::Result, Payload>;
52template<
typename Payload =
void>
53using ErrorIq = Iq<IqType::Error, Payload>;
55template<IqType Type,
typename Payload =
void>
56auto iqFromDomImpl(
const QDomElement &el) -> std::optional<Iq<Type, Payload>>;
58template<IqType Type,
typename Payload>
59 requires((Type == IqType::Get || Type == IqType::Set) && !std::is_void_v<Payload>)
60struct Iq<Type, Payload> {
67 using PayloadType = Payload;
68 static constexpr auto IqType = Type;
70 static std::optional<Iq> fromDom(
const QDomElement &el) {
return iqFromDomImpl<Type, Payload>(el); }
71 void toXml(XmlWriter &w)
const
75 Attribute { u
"id",
id },
76 OptionalAttribute { u
"from", from },
77 OptionalAttribute { u
"to", to },
78 Attribute { u
"type", Type },
79 OptionalAttribute { u
"xml:lang", lang },
85template<
typename Payload>
86struct Iq<IqType::
Result, Payload> {
91 std::conditional_t<std::is_void_v<Payload>, std::monostate, Payload> payload;
93 using PayloadType = Payload;
95 static std::optional<Iq> fromDom(
const QDomElement &el) {
return iqFromDomImpl<IqType::Result, Payload>(el); }
96 void toXml(XmlWriter &w)
const
100 Attribute { u
"id",
id },
101 OptionalAttribute { u
"from", from },
102 OptionalAttribute { u
"to", to },
103 Attribute { u
"type", IqType::Result },
104 OptionalAttribute { u
"xml:lang", lang },
110template<
typename Payload>
111struct Iq<IqType::Error, Payload> {
116 std::conditional_t<std::is_void_v<Payload>, std::monostate, std::optional<Payload>> payload;
119 using PayloadType = Payload;
121 static std::optional<Iq> fromDom(
const QDomElement &el) {
return iqFromDomImpl<IqType::Error, Payload>(el); }
122 void toXml(XmlWriter &w)
const
126 Attribute { u
"id",
id },
127 OptionalAttribute { u
"from", from },
128 OptionalAttribute { u
"to", to },
129 Attribute { u
"type", IqType::Error },
130 OptionalAttribute { u
"xml:lang", lang },
137template<IqType Type,
typename Payload>
138auto iqFromDomImpl(
const QDomElement &el) -> std::optional<Iq<Type, Payload>>
140 using IqT = Iq<Type, Payload>;
142 if (el.tagName() == u
"iq" && el.hasAttribute(u
"id"_s) && el.attribute(u
"type"_s) == Type) {
143 auto id = el.attribute(u
"id"_s);
144 auto from = el.attribute(u
"from"_s);
145 auto to = el.attribute(u
"to"_s);
146 auto lang = el.attributeNS(staticString(ns_xml), u
"lang"_s);
148 if constexpr (Type == IqType::Get || Type == IqType::Set) {
149 if (
auto payload = parseOptionalElement<Payload>(el.firstChildElement())) {
158 }
else if constexpr (Type == IqType::Result) {
159 if constexpr (std::is_void_v<Payload>) {
160 return IqT { std::move(
id), std::move(from), std::move(to), std::move(lang) };
162 if (
auto payload = parseOptionalElement<Payload>(el.firstChildElement())) {
172 }
else if constexpr (Type == IqType::Error) {
173 auto errorEl = el.lastChildElement();
174 auto payloadEl = errorEl.previousSiblingElement();
176 if (
auto error = parseOptionalElement<QXmppStanza::Error>(errorEl)) {
182 parseOptionalElement<Payload>(payloadEl),
192template<
typename Payload>
193auto parseIqResponse(std::variant<QDomElement, QXmppError> &&sendResult) -> std::variant<Payload, QXmppStanza::Error, QXmppError>
196 using Result = std::variant<Payload, QXmppStanza::Error, QXmppError>;
199 [](QDomElement &&el) -> Result {
200 auto type = el.attribute(u
"type"_s);
201 if (type == IqType::Result) {
202 if (
auto payload = parseElement<Payload>(el.firstChildElement())) {
203 return std::move(*payload);
206 u
"Failed to parse IQ result payload"_s,
207 StanzaError(StanzaError::Cancel, StanzaError::UndefinedCondition),
210 }
else if (type == IqType::Error) {
211 if (
auto error = parseElement<StanzaError>(el.lastChildElement())) {
212 return std::move(*error);
214 return QXmppError { u
"Failed to parse error response"_s, {} };
217 return QXmppError { u
"Received unexpected IQ type"_s, {} };
220 std::move(sendResult));
223template<
typename Payload>
224auto parseIqResponseFlat(std::variant<QDomElement, QXmppError> &&sendResult)
226 using Result = std::variant<Payload, QXmppError>;
229 parseIqResponse<Payload>(std::move(sendResult)));
233template<
typename Payload>
237 std::optional<Payload> payload;
239 template<IqType Type>
240 requires(Type == IqType::Get || Type == IqType::Set || Type == IqType::Result)
241 CompatIq(Iq<Type, Payload> &&iq) :
QXmppIq(), payload(std::move(iq.payload))
247 if constexpr (Type == IqType::Get) {
249 }
else if constexpr (Type == IqType::Set) {
251 }
else if constexpr (Type == IqType::Result) {
253 }
else if constexpr (Type == IqType::Error) {
258 CompatIq(
QXmppIq::Type type, std::optional<Payload> &&payload = {})
259 :
QXmppIq(type), payload(std::move(payload))
263 void parseElementFromChild(
const QDomElement &el)
override
265 payload = parseElement<Payload>(el.firstChildElement());
267 void toXmlElementFromChild(QXmlStreamWriter *writer)
const override
269 XmlWriter(writer).write(payload);
273template<IqType Type,
typename Payload>
274CompatIq(Iq<Type, Payload> &&) -> CompatIq<Payload>;
276template<
typename Payload>
The QXmppIq class is the base class for all IQs.
Definition QXmppIq.h:23
Type
This enum describes the type of IQ.
Definition QXmppIq.h:26
@ Set
Set request.
Definition QXmppIq.h:29
@ Get
Get request.
Definition QXmppIq.h:28
@ Result
Result.
Definition QXmppIq.h:30
void setType(QXmppIq::Type)
Definition QXmppIq.cpp:70
The Error class represents a stanza error.
Definition QXmppStanza.h:112
void setLang(const QString &)
Definition QXmppStanza.cpp:778
void setFrom(const QString &)
Definition QXmppStanza.cpp:742
void setTo(const QString &)
Definition QXmppStanza.cpp:724
void setId(const QString &)
Definition QXmppStanza.cpp:760
std::variant< T, QXmppError > Result
Definition QXmppGlobal.h:209
Definition QXmppError.h:17