QXmpp Version: 1.15.1
Loading...
Searching...
No Matches
QXmppAsync_p.h
1// SPDX-FileCopyrightText: 2021 Linus Jahn <lnj@kaidan.im>
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4
5#ifndef QXMPPASYNC_P_H
6#define QXMPPASYNC_P_H
7
8#include "QXmppTask.h"
9#include "QXmppVisitHelper_p.h"
10
11#include <variant>
12
13class QDomElement;
14struct QXmppError;
15
16namespace QXmpp::Private {
17
18// creates a task in finished state with value
19template<typename T>
20QXmppTask<T> makeReadyTask(T &&value) { co_return value; }
21inline QXmppTask<void> makeReadyTask() { co_return; }
22
23// Attaches to existing promise
24template<typename Result, typename Input, typename Converter>
25auto chain(QXmppTask<Input> &&source, QObject *context, QXmppPromise<Result> &&p, Converter convert)
26{
27 if constexpr (std::is_void_v<Input>) {
28 source.then(context, [p = std::move(p), convert = std::move(convert)]() mutable {
29 if constexpr (std::is_void_v<Result>) {
30 convert();
31 p.finish();
32 } else {
33 p.finish(convert());
34 }
35 });
36 } else {
37 source.then(context, [p = std::move(p), convert = std::move(convert)](Input &&input) mutable {
38 if constexpr (std::is_void_v<Result>) {
39 convert(std::move(input));
40 p.finish();
41 } else {
42 p.finish(convert(std::move(input)));
43 }
44 });
45 }
46}
47
48// creates new task which converts the result of the first
49template<typename Result, typename Input, typename Converter>
50auto chain(QXmppTask<Input> &&source, QObject *context, Converter convert) -> QXmppTask<Result>
51{
53 auto task = p.task();
54 if constexpr (std::is_void_v<Input>) {
55 source.then(context, [p = std::move(p), convert = std::move(convert)]() mutable {
56 if constexpr (std::is_void_v<Result>) {
57 convert();
58 p.finish();
59 } else {
60 p.finish(convert());
61 }
62 });
63 } else {
64 source.then(context, [p = std::move(p), convert = std::move(convert)](Input &&input) mutable {
65 if constexpr (std::is_void_v<Result>) {
66 convert(std::move(input));
67 p.finish();
68 } else {
69 p.finish(convert(std::move(input)));
70 }
71 });
72 }
73 return task;
74}
75
76// parse Iq type from QDomElement or pass error
77template<typename IqType, typename Converter>
78auto parseIq(std::variant<QDomElement, QXmppError> &&sendResult, Converter convert)
79{
80 using Result = std::invoke_result_t<Converter, IqType &&>;
81 return std::visit(
82 overloaded {
83 [convert = std::move(convert)](const QDomElement &element) -> Result {
84 IqType iq;
85 iq.parse(element);
86 return convert(std::move(iq));
87 },
88 [](QXmppError &&error) -> Result {
89 return error;
90 },
91 },
92 std::move(sendResult));
93}
94
95template<typename IqType>
96auto parseIq(std::variant<QDomElement, QXmppError> &&sendResult) -> std::variant<IqType, QXmppError>
97{
98 return parseIq<IqType>(std::move(sendResult), [](IqType &&iq) {
99 return std::variant<IqType, QXmppError> { iq };
100 });
101}
102
103} // namespace QXmpp::Private
104
105#endif // QXMPPASYNC_P_H
Create and update QXmppTask objects to communicate results of asynchronous operations.
Definition QXmppTask.h:81
QXmppTask< T > task()
Definition QXmppTask.h:167
void finish()
Definition QXmppTask.h:184
Definition QXmppTask.h:330
std::variant< T, QXmppError > Result
Definition QXmppGlobal.h:209
Definition QXmppError.h:17