1 #ifndef QTRESTCLIENT_HELPERTYPES_H 
    2 #define QTRESTCLIENT_HELPERTYPES_H 
    4 #include "QtRestClient/qtrestclient_global.h" 
    9 #include <QtCore/qcborvalue.h> 
   10 #include <QtCore/qcbormap.h> 
   11 #include <QtCore/qcborarray.h> 
   12 #include <QtCore/qjsonvalue.h> 
   13 #include <QtCore/qjsonobject.h> 
   14 #include <QtCore/qjsonarray.h> 
   16 namespace QtRestClient::__private {
 
   18 template<
typename... Ts>
 
   19 struct overload : 
public Ts... {
 
   20     using Ts::operator()...;
 
   23 overload(Ts...) -> overload<Ts...>;
 
   27 using DataType = std::variant<std::nullopt_t, QCborValue, QJsonValue>;
 
   28 using FunctionType = std::function<void(
int, DataType)>;
 
   30 template <
typename... TArgs>
 
   34 struct FnBinder<int, DataType> {
 
   35     template <
typename TFn>
 
   36     static inline FunctionType bind(TFn &&fn) {
 
   37         return std::forward<TFn>(fn);
 
   43     template <
typename TFn>
 
   44     static inline FunctionType bind(TFn &&fn) {
 
   45         return [xFn = std::forward<TFn>(fn)](int, 
const DataType &) {
 
   52 struct FnBinder<int> {
 
   53     template <
typename TFn>
 
   54     static inline FunctionType bind(TFn &&fn) {
 
   55         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &) {
 
   61 template <
typename TData>
 
   62 struct FnBinder<TData> {
 
   63     template <
typename TFn>
 
   64     static inline FunctionType bind(TFn &&fn) {
 
   65         return FnBinder<int, TData>::bind([xFn = std::forward<TFn>(fn)](
int, 
const TData &value) {  
 
   73     template <
typename TFn>
 
   74     static inline FunctionType bind(TFn &&fn) {
 
   75         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
   77                            [xFn, code](std::nullopt_t){
 
   81                                qCWarning(logGlobal) << 
"CBOR data in JSON callback - discarding";
 
   93     template <
typename TFn>
 
   94     static inline FunctionType bind(TFn &&fn) {
 
   95         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
   97                            [xFn, code](std::nullopt_t){
 
  101                                qCWarning(logGlobal) << 
"CBOR data in JSON callback - discarding";
 
  104                                xFn(code, vValue.toObject());
 
  113     template <
typename TFn>
 
  114     static inline FunctionType bind(TFn &&fn) {
 
  115         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
  116             std::visit(overload {
 
  117                            [xFn, code](std::nullopt_t){
 
  121                                qCWarning(logGlobal) << 
"CBOR data in JSON callback - discarding";
 
  124                                xFn(code, vValue.toArray());
 
  133     template <
typename TFn>
 
  134     static inline FunctionType bind(TFn &&fn) {
 
  135         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
  136             std::visit(overload {
 
  137                            [xFn, code](std::nullopt_t){
 
  138                                xFn(code, 
QCborValue{QCborSimpleType::Undefined});
 
  144                                qCWarning(logGlobal) << 
"JSON data in CBOR callback - discarding";
 
  153     template <
typename TFn>
 
  154     static inline FunctionType bind(TFn &&fn) {
 
  155         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
  156             std::visit(overload {
 
  157                            [xFn, code](std::nullopt_t){
 
  161                                xFn(code, vValue.toMap());
 
  164                                qCWarning(logGlobal) << 
"JSON data in CBOR callback - discarding";
 
  173     template <
typename TFn>
 
  174     static inline FunctionType bind(TFn &&fn) {
 
  175         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
  176             std::visit(overload {
 
  177                            [xFn, code](std::nullopt_t){
 
  181                                xFn(code, vValue.toArray());
 
  184                                qCWarning(logGlobal) << 
"JSON data in CBOR callback - discarding";
 
  191 template <
typename TCbor, 
typename TJson>
 
  192 struct FnBinder<int, std::variant<std::nullopt_t, TCbor, TJson>> {
 
  193     template <
typename TFn>
 
  194     static inline FunctionType bind(TFn &&fn) {
 
  195         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
  196             auto cFn = FnBinder<int, TCbor>::bind(xFn)(code, value);
 
  197             auto jFn = FnBinder<int, TJson>::bind(xFn)(code, value);
 
  198             std::visit(overload {
 
  199                            [xFn, code](std::nullopt_t){
 
  200                                xFn(code, std::nullopt);
 
  202                            [xcFn = std::move(cFn), code](
const QCborValue &vValue){
 
  205                            [xjFn = std::move(jFn), code](
const QJsonValue &vValue){
 
  213 template <
typename TCbor, 
typename TJson>
 
  214 struct FnBinder<int, std::variant<TCbor, TJson>> {
 
  215     template <
typename TFn>
 
  216     static inline FunctionType bind(TFn &&fn) {
 
  217         return [xFn = std::forward<TFn>(fn)](
int code, 
const DataType &value) {
 
  218             auto cFn = FnBinder<int, TCbor>::bind(xFn)(code, value);
 
  219             auto jFn = FnBinder<int, TJson>::bind(xFn)(code, value);
 
  220             std::visit(overload {
 
  221                            [xFn, code](std::nullopt_t){
 
  222                                xFn(code, std::variant<TCbor, TJson>{});
 
  224                            [xcFn = std::move(cFn), code](
const QCborValue &vValue){
 
  227                            [xjFn = std::move(jFn), code](
const QJsonValue &vValue){
 
  237 template <
typename T>
 
  238 struct FnInfo : 
public FnInfo<decltype(&T::operator())> {};
 
  240 template <
typename TClass, 
typename TRet, 
typename... TArgs>
 
  241 struct FnInfo<TRet(TClass::*)(TArgs...) const>
 
  243     using Binder = FnBinder<std::decay_t<TArgs>...>;
 
  246 template <
typename TClass, 
typename TRet, 
typename... TArgs>
 
  247 struct FnInfo<TRet(TClass::*)(TArgs...)>
 
  249     using Binder = FnBinder<std::decay_t<TArgs>...>;
 
  252 template <
typename TRet, 
typename... TArgs>
 
  253 struct FnInfo<TRet(*)(TArgs...)>
 
  255     using Binder = FnBinder<std::decay_t<TArgs>...>;
 
  258 template <
typename TClass, 
typename TRet, 
typename... TBinders, 
typename... TArgs>
 
  259 struct FnInfo<TRet(TClass::*(TBinders...))(TArgs...) const>
 
  261     using Binder = FnBinder<std::decay_t<TArgs>...>;
 
  264 template <
typename TClass, 
typename TRet, 
typename... TBinders, 
typename... TArgs>
 
  265 struct FnInfo<TRet(TClass::*(TBinders...))(TArgs...)>
 
  267     using Binder = FnBinder<std::decay_t<TArgs>...>;
 
  272 template <
typename TFn>
 
  273 static inline __binder::FunctionType bindCallback(TFn &&fn) {
 
  274     return __binder::FnInfo<std::decay_t<TFn>>::Binder::bind(std::forward<TFn>(fn));
 
  277 template <
typename TFn, 
typename TError>
 
  278 static inline __binder::FunctionType bindCallback(
const std::function<
void(
QString, 
int, TError)> &handler, TFn &&tFn, TError errorType) {
 
  279     return bindCallback([handler, xTFn = std::forward<TFn>(tFn), errorType](
int code, 
auto &&data) {
 
  280         handler(xTFn(data, code), code, errorType);
 
  286 #endif // QTRESTCLIENT_HELPERTYPES_H