LeechCraft 0.6.70-17609-g3dde4097dd
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
handlenetworkreply.h
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <QNetworkReply>
12#include <util/sll/either.h>
13#include <util/sll/void.h>
14#include <util/sll/typelist.h>
16#include "networkconfig.h"
17
18namespace LC::Util
19{
20 template<typename F>
21 void HandleNetworkReply (QObject *context, QNetworkReply *reply, F f)
22 {
23 QObject::connect (reply,
24 &QNetworkReply::finished,
25 context,
26 [reply, f]
27 {
28 reply->deleteLater ();
29 f (reply->readAll ());
30 });
31 }
32
33 template<typename>
34 struct ErrorInfo;
35
36 template<typename>
37 struct ResultInfo;
38
40 {
41 int Code_;
42 QByteArray Data_;
43 QHash<QByteArray, QList<QByteArray>> Headers_;
44
45 explicit ReplyWithHeaders (QNetworkReply*);
46 };
47
49 {
50 QNetworkReply::NetworkError Error_;
51 QString ErrorString_;
52
54
55 explicit ReplyError (QNetworkReply*);
56 };
57
58 template<typename... Args>
59 auto HandleReply (QNetworkReply *reply, QObject *context)
60 {
61 using Err = Find<ErrorInfo, Void, Args...>;
62 using Res = Find<ResultInfo, QByteArray, Args...>;
63
64 using Result_t = Either<Err, Res>;
65 QFutureInterface<Result_t> promise;
66 promise.reportStarted ();
67
68 QObject::connect (reply,
69 &QNetworkReply::finished,
70 context,
71 [promise, reply] () mutable
72 {
73 reply->deleteLater ();
74
75 if constexpr (std::is_same_v<Res, QByteArray>)
76 Util::ReportFutureResult (promise, reply->readAll ());
77 else if constexpr (std::is_same_v<Res, ReplyWithHeaders>)
78 Util::ReportFutureResult (promise, Res { reply });
79 else
80 static_assert (std::is_same_v<Res, struct Dummy>, "Unsupported reply type");
81 });
82 QObject::connect (reply,
83 &QNetworkReply::errorOccurred,
84 context,
85 [promise, reply] () mutable
86 {
87 reply->deleteLater ();
88
89 auto report = [&] (const Err& val) { Util::ReportFutureResult (promise, Left { val }); };
90
91 if constexpr (std::is_same_v<Err, QString>)
92 report (reply->errorString ());
93 else if constexpr (std::is_same_v<Err, Void>)
94 report ({});
95 else if constexpr (std::is_same_v<Err, ReplyError>)
96 report (Err { reply });
97 else
98 static_assert (std::is_same_v<Err, struct Dummy>, "Unsupported error type");
99 });
100
101 return promise.future ();
102 }
103
104 template<typename... Args>
105 auto HandleReplySeq (QNetworkReply *reply, QObject *context)
106 {
107 return Sequence (context, HandleReply<Args...> (reply, context));
108 }
109}
auto HandleReply(QNetworkReply *reply, QObject *context)
typename detail::Find< Name, Def, Args... >::type Find
Definition typelist.h:176
void HandleNetworkReply(QObject *context, QNetworkReply *reply, F f)
auto HandleReplySeq(QNetworkReply *reply, QObject *context)
#define UTIL_NETWORK_API
ReplyError(QNetworkReply *)
QNetworkReply::NetworkError Error_
QHash< QByteArray, QList< QByteArray > > Headers_
A proper void type, akin to unit (or ()) type in functional languages.
Definition void.h:21