QtRestClient  3.0.0
A library for generic JSON-based REST-APIs, with a mechanism to map JSON to Qt objects
simple.h
Go to the documentation of this file.
1 #ifndef QTRESTCLIENT_SIMPLEBASE_H
2 #define QTRESTCLIENT_SIMPLEBASE_H
3 
4 #include "QtRestClient/qtrestclient_global.h"
5 #include "QtRestClient/genericrestreply.h"
6 #include "QtRestClient/restclass.h"
7 
8 #include <functional>
9 
10 #include <QtCore/qpointer.h>
11 #include <QtCore/qsharedpointer.h>
12 #include <QtCore/qscopedpointer.h>
13 
14 namespace QtRestClient {
15 
17 template <typename T, typename = void>
18 class Simple;
19 
21 template<typename T>
22 class Simple<T*, std::enable_if_t<std::is_base_of_v<QObject, T>>> : public QObject
23 {
24 public:
26  Simple(QObject *parent = nullptr);
27 
29  virtual QUrl extensionHref() const = 0;
31  bool hasExtension() const;
33  bool isExtended() const;
38  T *currentExtended() const;
39 
43  template<typename ET = QObject*>
44  GenericRestReply<T*, ET> *extend(RestClient *client);
45 
57  template<typename ET = QObject*>
58  void extend(RestClient *client,
59  std::function<void(T*, bool)> extensionHandler,
60  const std::function<void(QString, int, RestReply::Error)> &errorHandler = {},
61  std::function<QString(ET, int)> failureTransformer = {});
74  template<typename ET = QObject*>
75  void extend(RestClient *client,
76  QObject *scope,
77  std::function<void(T*, bool)> extensionHandler,
78  const std::function<void(QString, int, RestReply::Error)> &errorHandler = {},
79  std::function<QString(ET, int)> failureTransformer = {});
80 
81 private:
83  inline QPointer<T> &ext();
84  inline const QPointer<T> &ext() const;
85 };
86 
88 template<typename T>
89 class Simple<T, std::enable_if_t<std::is_void_v<typename T::QtGadgetHelper>>>
90 {
91 public:
93  Simple();
94  inline virtual ~Simple() = default;
95 
97  virtual QUrl extensionHref() const = 0;
99  bool hasExtension() const;
101  bool isExtended() const;
105  T currentExtended() const;
106 
110  template<typename ET = QObject*>
111  GenericRestReply<T, ET> *extend(RestClient *client);
112 
124  template<typename ET = QObject*>
125  void extend(RestClient *client,
126  std::function<void(T, bool)> extensionHandler,
127  const std::function<void(QString, int, RestReply::Error)> &errorHandler = {},
128  std::function<QString(ET, int)> failureTransformer = {});
141  template<typename ET = QObject*>
142  void extend(RestClient *client,
143  QObject *scope,
144  std::function<void(T, bool)> extensionHandler,
145  const std::function<void(QString, int, RestReply::Error)> &errorHandler = {},
146  std::function<QString(ET, int)> failureTransformer = {});
147 
148 private:
150  inline QScopedPointer<T> &ext();
151  inline const QScopedPointer<T> &ext() const;
152 };
153 
154 }
155 
157 #define QTRESTCLIENT_EXT_HREF_PROP(x) \
158  inline QUrl extensionHref() const override { \
159  return property(#x).toUrl();\
160  }
161 
162 // ------------- Generic Implementation object -------------
163 
164 namespace QtRestClient {
165 
166 template<typename T>
168  QObject{parent},
169  _ext{new QPointer<T>{}}
170 {}
171 
172 template<typename T>
174 {
175  return extensionHref().isValid();
176 }
177 
178 template<typename T>
180 {
181  return ext();
182 }
183 
184 template<typename T>
186 {
187  return ext();
188 }
189 
190 template<typename T>
191 template<typename ET>
193 {
194  if (hasExtension()) {
195  QWeakPointer<QPointer<T>> extRef = _ext;
196  return client->rootClass()->get<T*, ET>(extensionHref())
197  ->onSucceeded([extRef](int, T *data) {
198  if (const auto ext = extRef.toStrongRef(); ext)
199  *ext = data;
200  });
201  } else
202  return nullptr;
203 }
204 
205 template<typename T>
206 template<typename ET>
207 void Simple<T*, std::enable_if_t<std::is_base_of_v<QObject, T>>>::extend(RestClient *client, std::function<void (T *, bool)> extensionHandler, const std::function<void (QString, int, RestReply::Error)> &errorHandler, std::function<QString (ET, int)> failureTransformer)
208 {
209  extend(client,
211  std::move(extensionHandler),
212  errorHandler,
213  std::move(failureTransformer));
214 }
215 
216 template<typename T>
217 template<typename ET>
218 void Simple<T*, std::enable_if_t<std::is_base_of_v<QObject, T>>>::extend(RestClient *client, QObject *scope, std::function<void (T *, bool)> extensionHandler, const std::function<void (QString, int, RestReply::Error)> &errorHandler, std::function<QString (ET, int)> failureTransformer)
219 {
220  if (ext())
221  extensionHandler(ext(), false);
222  else if(hasExtension()) {
223  QWeakPointer<QPointer<T>> extRef = _ext;
224  client->rootClass()->get<T*, ET>(extensionHref())
225  ->onSucceeded(scope, [extRef, xEH = std::move(extensionHandler)](int, T *data){
226  if (const auto ext = extRef.toStrongRef(); ext)
227  *ext = data;
228  xEH(data, true);
229  })
230  ->onAllErrors(scope, errorHandler, std::move(failureTransformer));
231  }
232 }
233 
234 template<typename T>
236 {
237  return *_ext;
238 }
239 
240 template<typename T>
242 {
243  return *_ext;
244 }
245 
246 // ------------- Generic Implementation gadget -------------
247 
248 template<typename T>
250  _ext{new QScopedPointer<T>{nullptr}}
251 {}
252 
253 template<typename T>
255 {
256  return extensionHref().isValid();
257 }
258 
259 template<typename T>
261 {
262  return ext();
263 }
264 
265 template<typename T>
267 {
268  if (ext())
269  return *(ext().data());
270  else
271  return {};
272 }
273 
274 template<typename T>
275 template<typename ET>
277 {
278  if (hasExtension()) {
279  QWeakPointer<QScopedPointer<T>> extRef = _ext;
280  return client->rootClass()->get<T, ET>(extensionHref())
281  ->onSucceeded([extRef](int, T data){
282  if (const auto ext = extRef.toStrongRef(); ext)
283  ext.data()->reset(new T{data});
284  });
285  } else
286  return nullptr;
287 }
288 
289 template<typename T>
290 template<typename ET>
291 void Simple<T, std::enable_if_t<std::is_void_v<typename T::QtGadgetHelper>>>::extend(RestClient *client, std::function<void (T, bool)> extensionHandler, const std::function<void (QString, int, RestReply::Error)> &errorHandler, std::function<QString (ET, int)> failureTransformer)
292 {
293  if (ext())
294  extensionHandler(*(ext().data()), false);
295  else if (hasExtension()) {
296  QWeakPointer<QScopedPointer<T>> extRef = _ext;
297  client->rootClass()->get<T, ET>(extensionHref())
298  ->onSucceeded([extRef, xEH = std::move(extensionHandler)](int, T data){
299  if (const auto ext = extRef.toStrongRef(); ext)
300  ext.data()->reset(new T{data});
301  xEH(data, true);
302  })
303  ->onAllErrors(errorHandler, std::move(failureTransformer));
304  }
305 }
306 
307 template<typename T>
308 template<typename ET>
309 void Simple<T, std::enable_if_t<std::is_void_v<typename T::QtGadgetHelper>>>::extend(RestClient *client, QObject *scope, std::function<void (T, bool)> extensionHandler, const std::function<void (QString, int, RestReply::Error)> &errorHandler, std::function<QString (ET, int)> failureTransformer)
310 {
311  if (ext())
312  extensionHandler(*(ext().data()), false);
313  else if (hasExtension()) {
314  QWeakPointer<QScopedPointer<T>> extRef = _ext;
315  client->rootClass()->get<T, ET>(extensionHref())
316  ->onSucceeded(scope, [extRef, xEH = std::move(extensionHandler)](int, T data){
317  if (const auto ext = extRef.toStrongRef(); ext)
318  ext.data()->reset(new T{data});
319  xEH(data, true);
320  })
321  ->onAllErrors(scope, errorHandler, std::move(failureTransformer));
322  }
323 }
324 
325 template<typename T>
327 {
328  return *_ext;
329 }
330 
331 template<typename T>
333 {
334  return *_ext;
335 }
336 
337 }
338 
339 #endif // QTRESTCLIENT_SIMPLEBASE_H
340 
QPointer
QtRestClient
The Namespace containing all classes of the QtRestClient module.
Definition: genericrestreply.h:14
QUrl
QtRestClient::RestReply::Error
Error
Defines the different possible error types.
Definition: restreply.h:45
QSharedPointer
QString
QtRestClient::GenericRestReply
A class to handle generic replies for generic requests.
Definition: genericrestreply.h:20
QtRestClient::RestClient::rootClass
RestClass * rootClass() const
Returns the rest class with the root path.
Definition: restclient.cpp:43
QScopedPointer
QtRestClient::Simple
A base class to create a simply type version for a normal one. Check The QObject* or Q_GADGET version...
Definition: simple.h:18
QtRestClient::RestClass::get
GenericRestReply< DT, ET > * get(const QString &methodPath, const QVariantHash &parameters={}, const HeaderHash &headers={}) const
Performs GET-request with generic objects.
Definition: restclass.h:82
QWeakPointer
QObject
QtRestClient::RestClient
A class to define access to an API, with general settings.
Definition: restclient.h:30
QWeakPointer::toStrongRef
QSharedPointer< T > toStrongRef() const const