1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#ifndef QABSTRACTGRPCLIENT_H
6#define QABSTRACTGRPCLIENT_H
7
8#include <QtCore/QObject>
9#include <QtCore/QSharedPointer>
10#include <QtCore/QWeakPointer>
11#include <QtCore/qbytearray.h>
12#include <QtGrpc/qabstractgrpcchannel.h>
13#include <QtGrpc/qgrpcstatus.h>
14#include <QtGrpc/qtgrpcglobal.h>
15#include <QtProtobuf/qabstractprotobufserializer.h>
16
17#include <memory>
18#include <optional>
19
20QT_BEGIN_NAMESPACE
21
22class QGrpcOperation;
23class QAbstractGrpcChannel;
24class QAbstractGrpcClientPrivate;
25
26class Q_GRPC_EXPORT QAbstractGrpcClient : public QObject
27{
28 Q_OBJECT
29
30public:
31 void attachChannel(const std::shared_ptr<QAbstractGrpcChannel> &channel);
32
33Q_SIGNALS:
34 void errorOccurred(const QGrpcStatus &status);
35
36protected:
37 explicit QAbstractGrpcClient(QLatin1StringView service, QObject *parent = nullptr);
38 ~QAbstractGrpcClient() override;
39
40 template <typename ParamType, typename ReturnType>
41 QGrpcStatus call(QLatin1StringView method, const QProtobufMessage &arg, ReturnType &ret,
42 const QGrpcCallOptions &options)
43 {
44 using namespace Qt::StringLiterals;
45 QGrpcStatus status{ QGrpcStatus::Unknown,
46 "Serializing failed. Serializer is not ready."_L1 };
47
48 std::optional<QByteArray> argData = trySerialize<ParamType>(arg);
49 if (argData) {
50 QByteArray retData;
51 status = call(method, arg: *argData, ret&: retData, options);
52 if (status == QGrpcStatus::StatusCode::Ok)
53 status = tryDeserialize(ret, retData);
54 }
55 return status;
56 }
57
58 template <typename ParamType>
59 std::shared_ptr<QGrpcCallReply> call(QLatin1StringView method, const QProtobufMessage &arg,
60 const QGrpcCallOptions &options)
61 {
62 std::optional<QByteArray> argData = trySerialize<ParamType>(arg);
63 if (!argData)
64 return {};
65 return call(method, arg: *argData, options);
66 }
67
68 template <typename ParamType>
69 std::shared_ptr<QGrpcStream> startStream(QLatin1StringView method, const QProtobufMessage &arg,
70 const QGrpcCallOptions &options)
71 {
72 std::optional<QByteArray> argData = trySerialize<ParamType>(arg);
73 if (!argData)
74 return {};
75 return startStream(method, arg: *argData, options);
76 }
77
78private:
79 QGrpcStatus call(QLatin1StringView method, QByteArrayView arg, QByteArray &ret,
80 const QGrpcCallOptions &options);
81
82 std::shared_ptr<QGrpcCallReply> call(QLatin1StringView method, QByteArrayView arg,
83 const QGrpcCallOptions &options);
84
85 std::shared_ptr<QGrpcStream> startStream(QLatin1StringView method, QByteArrayView arg,
86 const QGrpcCallOptions &options);
87
88 template <typename ReturnType>
89 QGrpcStatus tryDeserialize(ReturnType *ret, QByteArrayView retData)
90 {
91 auto _serializer = serializer();
92 if (_serializer == nullptr)
93 return QGrpcStatus::Unknown;
94 if (!_serializer->deserialize(ret, retData))
95 return handleDeserializationError(err: _serializer->deserializationError());
96 return QGrpcStatus::Ok;
97 }
98
99 template <typename ParamType>
100 std::optional<QByteArray> trySerialize(const QProtobufMessage &arg)
101 {
102 using namespace Qt::StringLiterals;
103 auto _serializer = serializer();
104 if (_serializer == nullptr) {
105 Q_EMIT errorOccurred(status: { QGrpcStatus::Unknown,
106 "Serializing failed. Serializer is not ready."_L1 });
107 return std::nullopt;
108 }
109 return _serializer->serialize<ParamType>(&arg);
110 }
111
112 std::shared_ptr<QAbstractProtobufSerializer> serializer() const;
113
114 QGrpcStatus handleDeserializationError(
115 const QAbstractProtobufSerializer::DeserializationError &err);
116
117 Q_DISABLE_COPY_MOVE(QAbstractGrpcClient)
118 Q_DECLARE_PRIVATE(QAbstractGrpcClient)
119};
120
121QT_END_NAMESPACE
122
123#endif // QABSTRACTGRPCLIENT_H
124

source code of qtgrpc/src/grpc/qabstractgrpcclient.h