Add the result metatype to QGrpcOperationContext

In certain usecases users might need to know the RPC result message
type. Currently we do not store it anywhere, so API users decide
how to deserialize message when calling QGrpcOperation::read method.

Add RCP methods overloads to QGrpcClientBase that accept the meta
types of the RPC result messages. Generate the code that uses these
overloads by default, sot QGrpcClientBase can store the information
about the result type inside the QGrpcOperationContext.

Introduce QGrpcOperation::responseMetaType,
QGrpcOperationContext::responseMetaType and
QGrpcOperationContext::setResponseMetaType methods.

These methods are user-facing API to access or change the result meta
type.

Task-number: QTBUG-128743
Change-Id: Ide0ebc1c935dfbdf0d3b62e05acdf058f95bf367
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
This commit is contained in:
Alexey Edelev 2024-09-12 11:55:04 +02:00
parent 21a3acb76a
commit a9bc44e092
14 changed files with 205 additions and 68 deletions

View File

@ -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

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtGrpc/private/qabstractgrpcchannel_p.h>
#include <QtGrpc/private/qgrpcoperation_p.h>
#include <QtGrpc/private/qtgrpclogging_p.h>
#include <QtGrpc/qgrpcclientbase.h>
#include <QtGrpc/qgrpcoperation.h>
@ -257,6 +258,13 @@ std::unique_ptr<QGrpcBidiStream> QGrpcClientBase::bidiStream(QLatin1StringView m
return d->initOperation<QGrpcBidiStream>(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);

View File

@ -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)

View File

@ -2,12 +2,13 @@
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtGrpc/private/qgrpcoperation_p.h>
#include <QtGrpc/private/qtgrpclogging_p.h>
#include <QtGrpc/qgrpcoperation.h>
#include <QtGrpc/qgrpcoperationcontext.h>
#include <QtCore/private/qobject_p.h>
#include <QtCore/qatomic.h>
#include <QtProtobuf/private/qprotobufmessage_p.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qeventloop.h>
#include <QtCore/qpointer.h>
@ -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<QGrpcOperationContext> &&operationContext_)
: operationContext(operationContext_)
{
}
QByteArray data;
std::shared_ptr<QGrpcOperationContext> operationContext;
QAtomicInteger<bool> isFinished{ false };
};
QGrpcOperation::QGrpcOperation(std::shared_ptr<QGrpcOperationContext> 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"

View File

@ -44,6 +44,8 @@ public:
[[nodiscard]] bool isFinished() const noexcept;
[[nodiscard]] QMetaType responseMetaType() const;
Q_SIGNALS:
void finished(const QGrpcStatus &status);

View File

@ -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 <QtGrpc/qgrpcoperation.h>
#include <QtCore/private/qobject_p.h>
#include <QtCore/qatomic.h>
QT_BEGIN_NAMESPACE
class QGrpcOperationPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGrpcOperation)
public:
explicit QGrpcOperationPrivate(std::shared_ptr<QGrpcOperationContext> &&operationContext_)
: operationContext(operationContext_)
{
}
~QGrpcOperationPrivate() override;
QByteArray data;
std::shared_ptr<QGrpcOperationContext> operationContext;
QAtomicInteger<bool> isFinished{ false };
static const QGrpcOperationPrivate *get(const QGrpcOperation *op) { return op->d_func(); }
};
QT_END_NAMESPACE
#endif // QTGRPCOPERATION_P_H

View File

@ -107,6 +107,7 @@ public:
QGrpcCallOptions options;
std::shared_ptr<QAbstractProtobufSerializer> serializer;
QHash<QByteArray, QByteArray> serverMetadata;
QMetaType responseMetaType;
};
QGrpcOperationContext::QGrpcOperationContext(QLatin1StringView method, QLatin1StringView service,
@ -200,6 +201,24 @@ void QGrpcOperationContext::setServerMetadata(QHash<QByteArray, QByteArray> &&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)
{

View File

@ -44,6 +44,9 @@ public:
void setServerMetadata(const QHash<QByteArray, QByteArray> &metadata);
void setServerMetadata(QHash<QByteArray, QByteArray> &&metadata);
[[nodiscard]] QMetaType responseMetaType() const;
void setResponseMetaType(QMetaType metaType);
[[nodiscard]] std::shared_ptr<const QAbstractProtobufSerializer> serializer() const;
Q_SIGNALS:

View File

@ -77,12 +77,17 @@ const char *GrpcTemplates::ClientMethodDefinitionAsyncTemplate()
return "\nstd::unique_ptr<QGrpcCallReply> $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<QGrpcCallReply> $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<QGrpc$stream_type$Stream> $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<QGrpc$stream_type$Stream> $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, "

View File

@ -15,43 +15,56 @@ Client::~Client() = default;
std::unique_ptr<QGrpcCallReply> Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg)
{
return call("testMethod"_L1, arg, {});
return testMethod(arg, {});
}
std::unique_ptr<QGrpcCallReply> 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<qtgrpc::tests::SimpleStringMessage>());
}
return reply;
}
std::unique_ptr<QGrpcServerStream> Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return serverStream("testMethodServerStream"_L1, arg, {});
}
return testMethodServerStream(arg, {});}
std::unique_ptr<QGrpcServerStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
std::unique_ptr<QGrpcClientStream> Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return clientStream("testMethodClientStream"_L1, arg, {});
}
return testMethodClientStream(arg, {});}
std::unique_ptr<QGrpcClientStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
std::unique_ptr<QGrpcBidiStream> Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return bidiStream("testMethodBiStream"_L1, arg, {});
}
return testMethodBiStream(arg, {});}
std::unique_ptr<QGrpcBidiStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
} // namespace TestService

View File

@ -15,13 +15,17 @@ Client::~Client() = default;
std::unique_ptr<QGrpcCallReply> Client::testMethod(const qtprotobufnamespace::tests::SimpleStringMessage &arg)
{
return call("testMethod"_L1, arg, {});
return testMethod(arg, {});
}
std::unique_ptr<QGrpcCallReply> 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<qtprotobufnamespace::tests::SimpleStringMessage>());
}
return reply;
}
} // namespace TestService

View File

@ -15,43 +15,56 @@ Client::~Client() = default;
std::unique_ptr<QGrpcCallReply> Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg)
{
return call("testMethod"_L1, arg, {});
return testMethod(arg, {});
}
std::unique_ptr<QGrpcCallReply> 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<qtgrpc::tests::SimpleStringMessage>());
}
return reply;
}
std::unique_ptr<QGrpcServerStream> Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return serverStream("testMethodServerStream"_L1, arg, {});
}
return testMethodServerStream(arg, {});}
std::unique_ptr<QGrpcServerStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
std::unique_ptr<QGrpcClientStream> Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return clientStream("testMethodClientStream"_L1, arg, {});
}
return testMethodClientStream(arg, {});}
std::unique_ptr<QGrpcClientStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
std::unique_ptr<QGrpcBidiStream> Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return bidiStream("testMethodBiStream"_L1, arg, {});
}
return testMethodBiStream(arg, {});}
std::unique_ptr<QGrpcBidiStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
} // namespace TestService

View File

@ -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<qtgrpc::tests::SimpleStringMessage>(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<qtgrpc::tests::SimpleStringMessage>(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<qtgrpc::tests::SimpleStringMessage>(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<qtgrpc::tests::SimpleStringMessage>(jsEngine,
std::move(stream), messageCallback, finishCallback, errorCallback);

View File

@ -15,43 +15,56 @@ Client::~Client() = default;
std::unique_ptr<QGrpcCallReply> Client::testMethod(const qtgrpc::tests::SimpleStringMessage &arg)
{
return call("testMethod"_L1, arg, {});
return testMethod(arg, {});
}
std::unique_ptr<QGrpcCallReply> 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<qtgrpc::tests::SimpleStringMessage>());
}
return reply;
}
std::unique_ptr<QGrpcServerStream> Client::testMethodServerStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return serverStream("testMethodServerStream"_L1, arg, {});
}
return testMethodServerStream(arg, {});}
std::unique_ptr<QGrpcServerStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
std::unique_ptr<QGrpcClientStream> Client::testMethodClientStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return clientStream("testMethodClientStream"_L1, arg, {});
}
return testMethodClientStream(arg, {});}
std::unique_ptr<QGrpcClientStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
std::unique_ptr<QGrpcBidiStream> Client::testMethodBiStream(const qtgrpc::tests::SimpleStringMessage &arg)
{
return bidiStream("testMethodBiStream"_L1, arg, {});
}
return testMethodBiStream(arg, {});}
std::unique_ptr<QGrpcBidiStream> 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<qtgrpc::tests::SimpleStringMessage>());
}
return stream;
}
} // namespace TestService