1 #ifndef QTRESTCLIENT_GENERICRESTREPLY_H
2 #define QTRESTCLIENT_GENERICRESTREPLY_H
4 #include "QtRestClient/qtrestclient_global.h"
5 #include "QtRestClient/restclient.h"
6 #include "QtRestClient/restreply.h"
7 #include "QtRestClient/paging_fwd.h"
8 #include "QtRestClient/metacomponent.h"
10 #include <type_traits>
12 #include <QtJsonSerializer/serializerbase.h>
16 template <
typename DataClassType,
typename ErrorClassType>
19 template <
typename DataClassType,
typename ErrorClassType>
23 template <
typename DataClassType,
typename ErrorClassType>
38 std::function<
QString(ErrorClassType,
int)> failureTransformer = {});
42 std::function<
QString(ErrorClassType,
int)> failureTransformer = {});
53 #ifdef QT_RESTCLIENT_USE_ASYNC
61 GenericRestReplyAwaitable<DataClassType, ErrorClassType>
awaitable();
68 #ifdef QT_RESTCLIENT_USE_ASYNC
82 template <
typename DataClassType,
typename ErrorClassType = QObject*>
83 class GenericRestReply :
public GenericRestReplyBase<DataClassType, ErrorClassType>
90 #ifdef QT_RESTCLIENT_USE_ASYNC
98 GenericRestReply<DataClassType, ErrorClassType> *
onSucceeded(std::function<
void(
int, DataClassType)> handler);
100 GenericRestReply<DataClassType, ErrorClassType> *
onSucceeded(
QObject *scope, std::function<
void(
int, DataClassType)> handler);
106 template <
typename ErrorClassType>
114 #ifdef QT_RESTCLIENT_USE_ASYNC
132 template <
typename DataClassType,
typename ErrorClassType>
140 #ifdef QT_RESTCLIENT_USE_ASYNC
158 std::function<
bool(DataClassType, qint64)> iterator,
168 std::function<void(
int, ErrorClassType)> _failureHandler;
175 #include "QtRestClient/paging.h"
181 template <
typename DataClassType,
typename ErrorClassType>
184 return onFailed(
this, std::move(handler));
187 template <
typename DataClassType,
typename ErrorClassType>
191 std::visit(__private::overload {
192 [&](std::nullopt_t) {
193 xHandler(code, ErrorClassType{});
197 xHandler(code, _client->serializer()->deserializeGeneric(data, qMetaTypeId<ErrorClassType>()).template value<ErrorClassType>());
199 if (_exceptionHandler)
200 _exceptionHandler(e);
201 xHandler(code, ErrorClassType{});
206 return static_cast<TInstance*>(
this);
209 template <
typename DataClassType,
typename ErrorClassType>
212 _exceptionHandler = std::move(handler);
213 return static_cast<TInstance*>(
this);
216 template <
typename DataClassType,
typename ErrorClassType>
219 return onAllErrors(
this, handler, std::move(failureTransformer));
222 template <
typename DataClassType,
typename ErrorClassType>
228 this->onFailed(scope, [handler, xFt = std::move(failureTransformer)](
int code, ErrorClassType obj){
230 handler(xFt(obj, code), code, Error::Failure);
232 handler({}, code, Error::Failure);
233 __private::MetaComponent<ErrorClassType>::deleteLater(obj);
235 this->onError(scope, handler);
236 return static_cast<TInstance*>(
this);
239 template <
typename DataClassType,
typename ErrorClassType>
242 return onCompleted(
this, std::move(handler));
245 template <
typename DataClassType,
typename ErrorClassType>
249 return static_cast<TInstance*>(
this);
252 template <
typename DataClassType,
typename ErrorClassType>
255 return onError(
this, std::move(handler));
258 template <
typename DataClassType,
typename ErrorClassType>
262 return static_cast<TInstance*>(
this);
265 #ifdef QT_RESTCLIENT_USE_ASYNC
266 template<
typename DataClassType,
typename ErrorClassType>
270 return static_cast<TInstance*>(
this);
274 template <
typename DataClassType,
typename ErrorClassType>
278 return static_cast<TInstance*>(
this);
281 #ifdef QT_RESTCLIENT_USE_ASYNC
282 template <
typename DataClassType,
typename ErrorClassType>
288 template<
typename DataClassType,
typename ErrorClassType>
289 GenericRestReplyBase<DataClassType, ErrorClassType>::GenericRestReplyBase(
const QFuture<QNetworkReply*> &networkReplyFuture, RestClient *client,
QObject *parent) :
290 RestReply{networkReplyFuture, client->asyncPool(), parent},
294 template <
typename DataClassType,
typename ErrorClassType>
295 GenericRestReplyBase<DataClassType, ErrorClassType>::GenericRestReplyBase(
QNetworkReply *networkReply, RestClient *client,
QObject *parent) :
296 RestReply{networkReply, parent},
303 template<
typename DataClassType,
typename ErrorClassType>
308 #ifdef QT_RESTCLIENT_USE_ASYNC
309 template<
typename DataClassType,
typename ErrorClassType>
315 template<
typename DataClassType,
typename ErrorClassType>
318 return onSucceeded(
this, std::move(handler));
321 template<
typename DataClassType,
typename ErrorClassType>
326 std::visit(__private::overload {
327 [&](std::nullopt_t) {
328 xFn(code, DataClassType{});
330 [&](
const auto &data) {
331 xFn(code, this->_client->serializer()->deserializeGeneric(data, qMetaTypeId<DataClassType>()).template value<DataClassType>());
335 if (this->_exceptionHandler)
336 this->_exceptionHandler(e);
344 template<
typename ErrorClassType>
348 this->setAllowEmptyReplies(
true);
351 #ifdef QT_RESTCLIENT_USE_ASYNC
352 template<
typename ErrorClassType>
356 this->setAllowEmptyReplies(
true);
360 template<
typename ErrorClassType>
366 template<
typename ErrorClassType>
375 template<
typename DataClassType,
typename ErrorClassType>
380 #ifdef QT_RESTCLIENT_USE_ASYNC
381 template<
typename DataClassType,
typename ErrorClassType>
387 template<
typename DataClassType,
typename ErrorClassType>
390 return onSucceeded(
this, handler);
393 template<
typename DataClassType,
typename ErrorClassType>
398 std::visit(__private::overload {
399 [&](std::nullopt_t) {
402 [&](
const auto &data) {
403 auto iPaging = this->_client->pagingFactory()->createPaging(this->_client->serializer(), data);
404 auto pData = this->_client->serializer()->deserializeGeneric(std::visit(__private::overload {
405 [](
const QCborArray &data) -> std::variant<QCborValue, QJsonValue> {
408 [](
const QJsonArray &data) -> std::variant<QCborValue, QJsonValue> {
411 }, iPaging->items()),
418 if (this->_exceptionHandler)
419 this->_exceptionHandler(e);
441 template<
typename DataClassType,
typename ErrorClassType>
444 return onSucceeded(
this, [
this, it = std::move(iterator), to, from](
int,
const Paging<DataClassType> &paging) {
446 paging.
iterate(it, this->_failureHandler, this->_errorHandler, this->_exceptionHandler, to, from);
467 template<
typename DataClassType,
typename ErrorClassType>
470 return onSucceeded(scope, [
this, scope, it = std::move(iterator), to, from](
int,
const Paging<DataClassType> &paging){
472 paging.
iterate(scope, it, this->_failureHandler, this->_errorHandler, this->_exceptionHandler, to, from);
476 template<
typename DataClassType,
typename ErrorClassType>
479 _failureHandler = std::move(handler);
483 template<
typename DataClassType,
typename ErrorClassType>
486 _errorHandler = std::move(handler);
492 #endif // QTRESTCLIENT_GENERICRESTREPLY_H