diff --git a/src/grpc/CMakeLists.txt b/src/grpc/CMakeLists.txt index e4e27d00..e39c01ce 100644 --- a/src/grpc/CMakeLists.txt +++ b/src/grpc/CMakeLists.txt @@ -3,7 +3,7 @@ qt_internal_add_module(Grpc SOURCES - qgrpcoperation.h qgrpcoperation.cpp + qgrpcoperation.h qgrpcoperation_p.h qgrpcoperation.cpp qgrpcoperationcontext.h qgrpcoperationcontext.cpp qgrpccallreply.h qgrpccallreply.cpp qgrpcstream.h qgrpcstream.cpp @@ -20,6 +20,7 @@ qt_internal_add_module(Grpc LIBRARIES Qt::CorePrivate Qt::NetworkPrivate + Qt::ProtobufPrivate PUBLIC_LIBRARIES Qt::Core Qt::Protobuf diff --git a/src/grpc/qgrpcclientbase.cpp b/src/grpc/qgrpcclientbase.cpp index 60b0f6c1..367b0a21 100644 --- a/src/grpc/qgrpcclientbase.cpp +++ b/src/grpc/qgrpcclientbase.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include +#include #include #include #include @@ -257,6 +258,13 @@ std::unique_ptr QGrpcClientBase::bidiStream(QLatin1StringView m return d->initOperation(method, arg, options); } +void QGrpcClientBase::setOperationResponseMetaType(QGrpcOperation *operation, + QMetaType responseMetaType) +{ + Q_ASSERT(operation); + QGrpcOperationPrivate::get(operation)->operationContext->setResponseMetaType(responseMetaType); +} + bool QGrpcClientBase::event(QEvent *event) { return QObject::event(event); diff --git a/src/grpc/qgrpcclientbase.h b/src/grpc/qgrpcclientbase.h index 6bc569bc..aaec83fe 100644 --- a/src/grpc/qgrpcclientbase.h +++ b/src/grpc/qgrpcclientbase.h @@ -56,6 +56,9 @@ protected: const QProtobufMessage &arg, const QGrpcCallOptions &options); + static void setOperationResponseMetaType(QGrpcOperation *operation, + QMetaType responseMetaType); + private: Q_DISABLE_COPY_MOVE(QGrpcClientBase) Q_DECLARE_PRIVATE(QGrpcClientBase) diff --git a/src/grpc/qgrpcoperation.cpp b/src/grpc/qgrpcoperation.cpp index 057c9f4f..33e8db6b 100644 --- a/src/grpc/qgrpcoperation.cpp +++ b/src/grpc/qgrpcoperation.cpp @@ -2,12 +2,13 @@ // Copyright (C) 2019 Alexey Edelev // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +#include #include #include #include -#include -#include +#include + #include #include #include @@ -16,6 +17,9 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; +QGrpcOperationPrivate::~QGrpcOperationPrivate() + = default; + /*! \class QGrpcOperation \inmodule QtGrpc @@ -38,20 +42,6 @@ using namespace Qt::StringLiterals; {ConnectionType}. */ -class QGrpcOperationPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QGrpcOperation) -public: - explicit QGrpcOperationPrivate(std::shared_ptr &&operationContext_) - : operationContext(operationContext_) - { - } - - QByteArray data; - std::shared_ptr operationContext; - QAtomicInteger isFinished{ false }; -}; - QGrpcOperation::QGrpcOperation(std::shared_ptr operationContext, QObject *parent) : QObject(*new QGrpcOperationPrivate(std::move(operationContext)), parent) @@ -114,6 +104,12 @@ bool QGrpcOperation::read(QProtobufMessage *message) const Q_D(const QGrpcOperation); const auto ser = d->operationContext->serializer(); Q_ASSERT_X(ser, "QGrpcOperation", "The serializer is null"); + + if (auto responseMetaType = d->operationContext->responseMetaType(); responseMetaType.isValid() + && QProtobufMessagePrivate::get(message)->metaObject != responseMetaType.metaObject()) { + qGrpcWarning("Operation result meta type doesn't match the message meta type."); + } + if (!ser->deserialize(message, d->data)) { qGrpcWarning() << "Unable to deserialize message(" << qToUnderlying(ser->lastError()) <<"): " << ser->lastErrorString(); @@ -183,6 +179,15 @@ bool QGrpcOperation::event(QEvent *event) return QObject::event(event); } +/*! + Returns the meta type of the RPC response message. + */ +QMetaType QGrpcOperation::responseMetaType() const +{ + Q_D(const QGrpcOperation); + return d->operationContext->responseMetaType(); +} + QT_END_NAMESPACE #include "moc_qgrpcoperation.cpp" diff --git a/src/grpc/qgrpcoperation.h b/src/grpc/qgrpcoperation.h index 6a75ec29..4e42b30b 100644 --- a/src/grpc/qgrpcoperation.h +++ b/src/grpc/qgrpcoperation.h @@ -44,6 +44,8 @@ public: [[nodiscard]] bool isFinished() const noexcept; + [[nodiscard]] QMetaType responseMetaType() const; + Q_SIGNALS: void finished(const QGrpcStatus &status); diff --git a/src/grpc/qgrpcoperation_p.h b/src/grpc/qgrpcoperation_p.h new file mode 100644 index 00000000..d52a8eb0 --- /dev/null +++ b/src/grpc/qgrpcoperation_p.h @@ -0,0 +1,44 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QTGRPCOPERATION_P_H +#define QTGRPCOPERATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGrpcOperationPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGrpcOperation) +public: + explicit QGrpcOperationPrivate(std::shared_ptr &&operationContext_) + : operationContext(operationContext_) + { + } + ~QGrpcOperationPrivate() override; + + QByteArray data; + std::shared_ptr operationContext; + QAtomicInteger isFinished{ false }; + + static const QGrpcOperationPrivate *get(const QGrpcOperation *op) { return op->d_func(); } +}; + +QT_END_NAMESPACE + +#endif // QTGRPCOPERATION_P_H diff --git a/src/grpc/qgrpcoperationcontext.cpp b/src/grpc/qgrpcoperationcontext.cpp index 3c4c4bba..41075df7 100644 --- a/src/grpc/qgrpcoperationcontext.cpp +++ b/src/grpc/qgrpcoperationcontext.cpp @@ -107,6 +107,7 @@ public: QGrpcCallOptions options; std::shared_ptr serializer; QHash serverMetadata; + QMetaType responseMetaType; }; QGrpcOperationContext::QGrpcOperationContext(QLatin1StringView method, QLatin1StringView service, @@ -200,6 +201,24 @@ void QGrpcOperationContext::setServerMetadata(QHash &&me d->serverMetadata = std::move(metadata); } +/*! + Returns the meta type of the RPC result message. + */ +QMetaType QGrpcOperationContext::responseMetaType() const +{ + Q_D(const QGrpcOperationContext); + return d->responseMetaType; +} + +/*! + Stores the \a metaType of the RPC result message. +*/ +void QGrpcOperationContext::setResponseMetaType(QMetaType metaType) +{ + Q_D(QGrpcOperationContext); + d->responseMetaType = metaType; +} + // For future extensions bool QGrpcOperationContext::event(QEvent *event) { diff --git a/src/grpc/qgrpcoperationcontext.h b/src/grpc/qgrpcoperationcontext.h index 75eca04d..f1c14dfb 100644 --- a/src/grpc/qgrpcoperationcontext.h +++ b/src/grpc/qgrpcoperationcontext.h @@ -44,6 +44,9 @@ public: void setServerMetadata(const QHash &metadata); void setServerMetadata(QHash &&metadata); + [[nodiscard]] QMetaType responseMetaType() const; + void setResponseMetaType(QMetaType metaType); + [[nodiscard]] std::shared_ptr serializer() const; Q_SIGNALS: diff --git a/src/tools/qtgrpcgen/grpctemplates.cpp b/src/tools/qtgrpcgen/grpctemplates.cpp index 227bb5b9..d193b5da 100644 --- a/src/tools/qtgrpcgen/grpctemplates.cpp +++ b/src/tools/qtgrpcgen/grpctemplates.cpp @@ -77,12 +77,17 @@ const char *GrpcTemplates::ClientMethodDefinitionAsyncTemplate() return "\nstd::unique_ptr $classname$::$method_name$(const $param_type$ " "&$param_name$)\n" "{\n" - " return call(\"$method_name$\"_L1, $param_name$, {});\n" + " return $method_name$($param_name$, {});\n" "}\n\n" "\nstd::unique_ptr $classname$::$method_name$(const $param_type$ " "&$param_name$, const QGrpcCallOptions &options)\n" "{\n" - " return call(\"$method_name$\"_L1, $param_name$, options);\n" + " auto reply = call(\"$method_name$\"_L1, $param_name$, options);\n" + " if (auto *replyPtr = reply.get(); replyPtr != nullptr) {\n" + " setOperationResponseMetaType(replyPtr," + " QMetaType::fromType<$return_type$>());\n" + " }\n" + " return reply;\n" "}\n\n"; } @@ -99,7 +104,7 @@ const char *GrpcTemplates::ClientMethodDefinitionQmlTemplate() "from JS engine context\";\n" " return;\n" " }\n\n" - " auto reply = call(\"$method_name$\"_L1, $param_name$," + " auto reply = Client::$method_name$($param_name$," " options ? options->options() : QGrpcCallOptions{});\n" " QtGrpcQuickFunctional::makeCallConnections<$return_type$>(jsEngine,\n" " std::move(reply), finishCallback, errorCallback);\n" @@ -121,14 +126,18 @@ const char *GrpcTemplates::ClientMethodStreamDefinitionTemplate() return "std::unique_ptr $classname$::$method_name$(" "const $param_type$ &$param_name$)\n" "{\n" - " return $stream_type_lower$Stream(\"$method_name$\"_L1, " - "$param_name$, {});\n" + " return $method_name$($param_name$, {});" "}\n\n" "std::unique_ptr $classname$::$method_name$(" "const $param_type$ &$param_name$, const QGrpcCallOptions &options)\n" "{\n" - " return $stream_type_lower$Stream(\"$method_name$\"_L1, " - "$param_name$, options);\n" + " auto stream = $stream_type_lower$Stream(\"$method_name$\"_L1, $param_name$," + " options);\n" + " if (auto *streamPtr = stream.get(); streamPtr != nullptr) {\n" + " setOperationResponseMetaType(streamPtr," + " QMetaType::fromType<$return_type$>());\n" + " }\n" + " return stream;\n" "}\n\n"; } @@ -197,7 +206,7 @@ const char *GrpcTemplates::ClientMethodServerStreamDefinitionQmlTemplate() "from JS engine context\";\n" " return;\n" " }\n\n" - " auto stream = serverStream(\"$method_name$\"_L1, $param_name$," + " auto stream = Client::$method_name$($param_name$," " options ? options->options() : QGrpcCallOptions{});\n" " QtGrpcQuickFunctional::makeServerStreamConnections<$return_type$>(jsEngine,\n" " std::move(stream),\n" @@ -219,8 +228,8 @@ const char *GrpcTemplates::ClientMethodClientStreamDefinitionQmlTemplate() "from JS engine context\";\n" " return nullptr;\n" " }\n\n" - " auto stream = clientStream(\"$method_name$\"_L1," - " $param_name$, options ? options->options() : QGrpcCallOptions{});\n" + " auto stream = Client::$method_name$($param_name$," + " options ? options->options() : QGrpcCallOptions{});\n" " auto *sender = new $sender_class_name$(stream.get());\n" " QtGrpcQuickFunctional::makeClientStreamConnections<$return_type$>(jsEngine,\n" " std::move(stream), finishCallback, errorCallback);\n" @@ -244,8 +253,8 @@ const char *GrpcTemplates::ClientMethodBidiStreamDefinitionQmlTemplate() "from JS engine context\";\n" " return nullptr;\n" " }\n\n" - " auto stream = bidiStream(\"$method_name$\"_L1," - " $param_name$, options ? options->options() : QGrpcCallOptions {});\n" + " auto stream = Client::$method_name$($param_name$," + " options ? options->options() : QGrpcCallOptions {});\n" " auto *sender = new $sender_class_name$(stream.get());\n" " QtGrpcQuickFunctional::makeBidiStreamConnections<$return_type$>(jsEngine,\n" " std::move(stream), messageCallback, finishCallback, " diff --git a/tests/auto/grpcgen/data/expected_result/folder/qtgrpc/tests/testservice_client.grpc.qpb.cpp b/tests/auto/grpcgen/data/expected_result/folder/qtgrpc/tests/testservice_client.grpc.qpb.cpp index 052d4404..69596c40 100644 --- a/tests/auto/grpcgen/data/expected_result/folder/qtgrpc/tests/testservice_client.grpc.qpb.cpp +++ b/tests/auto/grpcgen/data/expected_result/folder/qtgrpc/tests/testservice_client.grpc.qpb.cpp @@ -15,43 +15,56 @@ Client::~Client() = default; std::unique_ptr Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg) { - return call("testMethod"_L1, arg, {}); + return testMethod(arg, {}); } std::unique_ptr Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return call("testMethod"_L1, arg, options); + auto reply = call("testMethod"_L1, arg, options); + if (auto *replyPtr = reply.get(); replyPtr != nullptr) { + setOperationResponseMetaType(replyPtr, QMetaType::fromType()); + } + return reply; } std::unique_ptr Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return serverStream("testMethodServerStream"_L1, arg, {}); -} + return testMethodServerStream(arg, {});} std::unique_ptr Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return serverStream("testMethodServerStream"_L1, arg, options); + auto stream = serverStream("testMethodServerStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } std::unique_ptr Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return clientStream("testMethodClientStream"_L1, arg, {}); -} + return testMethodClientStream(arg, {});} std::unique_ptr Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return clientStream("testMethodClientStream"_L1, arg, options); + auto stream = clientStream("testMethodClientStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } std::unique_ptr Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return bidiStream("testMethodBiStream"_L1, arg, {}); -} + return testMethodBiStream(arg, {});} std::unique_ptr Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return bidiStream("testMethodBiStream"_L1, arg, options); + auto stream = bidiStream("testMethodBiStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } } // namespace TestService diff --git a/tests/auto/grpcgen/data/expected_result/no-options/testserivcenomessages_client.grpc.qpb.cpp b/tests/auto/grpcgen/data/expected_result/no-options/testserivcenomessages_client.grpc.qpb.cpp index e9741a36..dd361332 100644 --- a/tests/auto/grpcgen/data/expected_result/no-options/testserivcenomessages_client.grpc.qpb.cpp +++ b/tests/auto/grpcgen/data/expected_result/no-options/testserivcenomessages_client.grpc.qpb.cpp @@ -15,13 +15,17 @@ Client::~Client() = default; std::unique_ptr Client::testMethod(const qtprotobufnamespace::tests::SimpleStringMessage &arg) { - return call("testMethod"_L1, arg, {}); + return testMethod(arg, {}); } std::unique_ptr Client::testMethod(const qtprotobufnamespace::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return call("testMethod"_L1, arg, options); + auto reply = call("testMethod"_L1, arg, options); + if (auto *replyPtr = reply.get(); replyPtr != nullptr) { + setOperationResponseMetaType(replyPtr, QMetaType::fromType()); + } + return reply; } } // namespace TestService diff --git a/tests/auto/grpcgen/data/expected_result/no-options/testservice_client.grpc.qpb.cpp b/tests/auto/grpcgen/data/expected_result/no-options/testservice_client.grpc.qpb.cpp index 71954fb3..eedf62d1 100644 --- a/tests/auto/grpcgen/data/expected_result/no-options/testservice_client.grpc.qpb.cpp +++ b/tests/auto/grpcgen/data/expected_result/no-options/testservice_client.grpc.qpb.cpp @@ -15,43 +15,56 @@ Client::~Client() = default; std::unique_ptr Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg) { - return call("testMethod"_L1, arg, {}); + return testMethod(arg, {}); } std::unique_ptr Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return call("testMethod"_L1, arg, options); + auto reply = call("testMethod"_L1, arg, options); + if (auto *replyPtr = reply.get(); replyPtr != nullptr) { + setOperationResponseMetaType(replyPtr, QMetaType::fromType()); + } + return reply; } std::unique_ptr Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return serverStream("testMethodServerStream"_L1, arg, {}); -} + return testMethodServerStream(arg, {});} std::unique_ptr Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return serverStream("testMethodServerStream"_L1, arg, options); + auto stream = serverStream("testMethodServerStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } std::unique_ptr Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return clientStream("testMethodClientStream"_L1, arg, {}); -} + return testMethodClientStream(arg, {});} std::unique_ptr Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return clientStream("testMethodClientStream"_L1, arg, options); + auto stream = clientStream("testMethodClientStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } std::unique_ptr Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return bidiStream("testMethodBiStream"_L1, arg, {}); -} + return testMethodBiStream(arg, {});} std::unique_ptr Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return bidiStream("testMethodBiStream"_L1, arg, options); + auto stream = bidiStream("testMethodBiStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } } // namespace TestService diff --git a/tests/auto/grpcgen/data/expected_result/qml/qmltestservice_client.grpc.qpb.cpp b/tests/auto/grpcgen/data/expected_result/qml/qmltestservice_client.grpc.qpb.cpp index 7123ba12..6ada892e 100644 --- a/tests/auto/grpcgen/data/expected_result/qml/qmltestservice_client.grpc.qpb.cpp +++ b/tests/auto/grpcgen/data/expected_result/qml/qmltestservice_client.grpc.qpb.cpp @@ -23,7 +23,7 @@ void QmlClient::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, return; } - auto reply = call("testMethod"_L1, arg, options ? options->options() : QGrpcCallOptions{}); + auto reply = Client::testMethod(arg, options ? options->options() : QGrpcCallOptions{}); QtGrpcQuickFunctional::makeCallConnections(jsEngine, std::move(reply), finishCallback, errorCallback); } @@ -41,7 +41,7 @@ void QmlClient::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage return; } - auto stream = serverStream("testMethodServerStream"_L1, arg, options ? options->options() : QGrpcCallOptions{}); + auto stream = Client::testMethodServerStream(arg, options ? options->options() : QGrpcCallOptions{}); QtGrpcQuickFunctional::makeServerStreamConnections(jsEngine, std::move(stream), messageCallback, finishCallback, errorCallback); @@ -59,7 +59,7 @@ TestMethodClientStreamSender *QmlClient::testMethodClientStream(const qtgrpc::te return nullptr; } - auto stream = clientStream("testMethodClientStream"_L1, arg, options ? options->options() : QGrpcCallOptions{}); + auto stream = Client::testMethodClientStream(arg, options ? options->options() : QGrpcCallOptions{}); auto *sender = new TestMethodClientStreamSender(stream.get()); QtGrpcQuickFunctional::makeClientStreamConnections(jsEngine, std::move(stream), finishCallback, errorCallback); @@ -80,7 +80,7 @@ TestMethodBiStreamSender *QmlClient::testMethodBiStream(const qtgrpc::tests::Sim return nullptr; } - auto stream = bidiStream("testMethodBiStream"_L1, arg, options ? options->options() : QGrpcCallOptions {}); + auto stream = Client::testMethodBiStream(arg, options ? options->options() : QGrpcCallOptions {}); auto *sender = new TestMethodBiStreamSender(stream.get()); QtGrpcQuickFunctional::makeBidiStreamConnections(jsEngine, std::move(stream), messageCallback, finishCallback, errorCallback); diff --git a/tests/auto/grpcgen/data/expected_result/separate/grpc/qtgrpc/tests/testservice_client.grpc.qpb.cpp b/tests/auto/grpcgen/data/expected_result/separate/grpc/qtgrpc/tests/testservice_client.grpc.qpb.cpp index 052d4404..69596c40 100644 --- a/tests/auto/grpcgen/data/expected_result/separate/grpc/qtgrpc/tests/testservice_client.grpc.qpb.cpp +++ b/tests/auto/grpcgen/data/expected_result/separate/grpc/qtgrpc/tests/testservice_client.grpc.qpb.cpp @@ -15,43 +15,56 @@ Client::~Client() = default; std::unique_ptr Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg) { - return call("testMethod"_L1, arg, {}); + return testMethod(arg, {}); } std::unique_ptr Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return call("testMethod"_L1, arg, options); + auto reply = call("testMethod"_L1, arg, options); + if (auto *replyPtr = reply.get(); replyPtr != nullptr) { + setOperationResponseMetaType(replyPtr, QMetaType::fromType()); + } + return reply; } std::unique_ptr Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return serverStream("testMethodServerStream"_L1, arg, {}); -} + return testMethodServerStream(arg, {});} std::unique_ptr Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return serverStream("testMethodServerStream"_L1, arg, options); + auto stream = serverStream("testMethodServerStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } std::unique_ptr Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return clientStream("testMethodClientStream"_L1, arg, {}); -} + return testMethodClientStream(arg, {});} std::unique_ptr Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return clientStream("testMethodClientStream"_L1, arg, options); + auto stream = clientStream("testMethodClientStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } std::unique_ptr Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg) { - return bidiStream("testMethodBiStream"_L1, arg, {}); -} + return testMethodBiStream(arg, {});} std::unique_ptr Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg, const QGrpcCallOptions &options) { - return bidiStream("testMethodBiStream"_L1, arg, options); + auto stream = bidiStream("testMethodBiStream"_L1, arg, options); + if (auto *streamPtr = stream.get(); streamPtr != nullptr) { + setOperationResponseMetaType(streamPtr, QMetaType::fromType()); + } + return stream; } } // namespace TestService