8 #include "QXmppError.h" 10 #include "QXmppStanza.h" 11 #include "QXmppVisitHelper_p.h" 13 #include "XmlWriter.h" 29 struct Enums::Data<IqType> {
31 static constexpr
auto Values = makeValues<IqType>({
39 template<IqType,
typename Payload =
void>
42 template<
typename Payload =
void>
43 using GetIq = Iq<IqType::Get, Payload>;
45 template<
typename Payload =
void>
46 using SetIq = Iq<IqType::Set, Payload>;
48 template<
typename Payload =
void>
49 using ResultIq = Iq<IqType::Result, Payload>;
51 template<
typename Payload =
void>
52 using ErrorIq = Iq<IqType::Error, Payload>;
54 template<IqType Type,
typename Payload =
void>
55 auto iqFromDomImpl(
const QDomElement &el) -> std::optional<Iq<Type, Payload>>;
57 template<IqType Type,
typename Payload>
58 requires((Type == IqType::Get || Type == IqType::Set) && !std::is_void_v<Payload>)
59 struct Iq<Type, Payload> {
66 using PayloadType = Payload;
67 static constexpr
auto IqType = Type;
69 static std::optional<Iq> fromDom(
const QDomElement &el) {
return iqFromDomImpl<Type, Payload>(el); }
70 void toXml(XmlWriter &w)
const 74 Attribute { u
"id",
id },
75 OptionalAttribute { u
"from", from },
76 OptionalAttribute { u
"to", to },
77 Attribute { u
"type", Type },
78 OptionalAttribute { u
"xml:lang", lang },
84 template<
typename Payload>
85 struct Iq<IqType::
Result, Payload> {
90 std::conditional_t<std::is_void_v<Payload>, std::monostate, Payload> payload;
92 using PayloadType = Payload;
94 static std::optional<Iq> fromDom(
const QDomElement &el) {
return iqFromDomImpl<IqType::Result, Payload>(el); }
95 void toXml(XmlWriter &w)
const 99 Attribute { u
"id",
id },
100 OptionalAttribute { u
"from", from },
101 OptionalAttribute { u
"to", to },
102 Attribute { u
"type", IqType::Result },
103 OptionalAttribute { u
"xml:lang", lang },
109 template<
typename Payload>
110 struct Iq<IqType::Error, Payload> {
115 std::conditional_t<std::is_void_v<Payload>, std::monostate, std::optional<Payload>> payload;
118 using PayloadType = Payload;
120 static std::optional<Iq> fromDom(
const QDomElement &el) {
return iqFromDomImpl<IqType::Error, Payload>(el); }
121 void toXml(XmlWriter &w)
const 125 Attribute { u
"id",
id },
126 OptionalAttribute { u
"from", from },
127 OptionalAttribute { u
"to", to },
128 Attribute { u
"type", IqType::Error },
129 OptionalAttribute { u
"xml:lang", lang },
136 template<IqType Type,
typename Payload>
137 auto iqFromDomImpl(
const QDomElement &el) -> std::optional<Iq<Type, Payload>>
139 using IqT = Iq<Type, Payload>;
141 if (el.tagName() == u
"iq" && el.hasAttribute(u
"id"_s) && el.attribute(u
"type"_s) == Type) {
142 auto id = el.attribute(u
"id"_s);
143 auto from = el.attribute(u
"from"_s);
144 auto to = el.attribute(u
"to"_s);
145 auto lang = el.attributeNS(ns_xml.toString(), u
"lang"_s);
147 if constexpr (Type == IqType::Get || Type == IqType::Set) {
148 if (
auto payload = parseOptionalElement<Payload>(el.firstChildElement())) {
157 }
else if constexpr (Type == IqType::Result) {
158 if constexpr (std::is_void_v<Payload>) {
159 return IqT { std::move(
id), std::move(from), std::move(to), std::move(lang) };
161 if (
auto payload = parseOptionalElement<Payload>(el.firstChildElement())) {
171 }
else if constexpr (Type == IqType::Error) {
172 auto errorEl = el.lastChildElement();
173 auto payloadEl = errorEl.previousSiblingElement();
175 if (
auto error = parseOptionalElement<QXmppStanza::Error>(errorEl)) {
181 parseOptionalElement<Payload>(payloadEl),
191 template<
typename Payload>
192 auto parseIqResponse(std::variant<QDomElement, QXmppError> &&sendResult) -> std::variant<Payload, QXmppStanza::Error, QXmppError>
195 using Result = std::variant<Payload, QXmppStanza::Error, QXmppError>;
198 [](QDomElement &&el) ->
Result {
199 auto type = el.attribute(u
"type"_s);
200 if (type == IqType::Result) {
201 if (
auto payload = parseElement<Payload>(el.firstChildElement())) {
202 return std::move(*payload);
205 u
"Failed to parse IQ result payload"_s,
209 }
else if (type == IqType::Error) {
210 if (
auto error = parseElement<StanzaError>(el.lastChildElement())) {
211 return std::move(*error);
213 return QXmppError { u
"Failed to parse error response"_s, {} };
216 return QXmppError { u
"Received unexpected IQ type"_s, {} };
219 std::move(sendResult));
222 template<
typename Payload>
223 auto parseIqResponseFlat(std::variant<QDomElement, QXmppError> &&sendResult)
225 using Result = std::variant<Payload, QXmppError>;
228 parseIqResponse<Payload>(std::move(sendResult)));
232 template<
typename Payload>
233 class CompatIq :
public QXmppIq 236 std::optional<Payload> payload;
238 template<IqType Type>
239 requires(Type == IqType::Get || Type == IqType::Set || Type == IqType::Result)
240 CompatIq(Iq<Type, Payload> &&iq) :
QXmppIq(), payload(
std::move(iq.payload))
246 if constexpr (Type == IqType::Get) {
248 }
else if constexpr (Type == IqType::Set) {
250 }
else if constexpr (Type == IqType::Result) {
252 }
else if constexpr (Type == IqType::Error) {
257 CompatIq(
QXmppIq::Type type, std::optional<Payload> &&payload = {})
258 :
QXmppIq(type), payload(std::move(payload))
262 void parseElementFromChild(
const QDomElement &el)
override 264 payload = parseElement<Payload>(el.firstChildElement());
266 void toXmlElementFromChild(QXmlStreamWriter *writer)
const override 268 XmlWriter(writer).write(payload);
272 template<IqType Type,
typename Payload>
273 CompatIq(Iq<Type, Payload> &&) -> CompatIq<Payload>;
275 template<
typename Payload>
The error is not temporary.
Definition: QXmppStanza.h:120
void setId(const QString &)
Definition: QXmppStanza.cpp:760
void setTo(const QString &)
Definition: QXmppStanza.cpp:724
Definition: QXmppError.h:17
Definition: QXmppTask.h:646
Type
This enum describes the type of IQ.
Definition: QXmppIq.h:26
Result.
Definition: QXmppIq.h:30
An undefined condition was hit.
Definition: QXmppStanza.h:154
Set request.
Definition: QXmppIq.h:29
Get request.
Definition: QXmppIq.h:28
The QXmppIq class is the base class for all IQs.
Definition: QXmppIq.h:22
void setType(QXmppIq::Type)
Definition: QXmppIq.cpp:70
void setFrom(const QString &)
Definition: QXmppStanza.cpp:742
Definition: Algorithms.h:14
The Error class represents a stanza error.
Definition: QXmppStanza.h:111
void setLang(const QString &)
Definition: QXmppStanza.cpp:778
std::variant< T, QXmppError > Result
Definition: QXmppGlobal.h:209