1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtGrpc/qgrpccalloptions.h>
5
6#include <QtCore/qbytearray.h>
7#include <QtCore/qdebug.h>
8#include <QtCore/qvariant.h>
9
10QT_BEGIN_NAMESPACE
11
12using namespace Qt::StringLiterals;
13
14/*!
15 \class QGrpcCallOptions
16 \inmodule QtGrpc
17 \brief The QGrpcCallOptions class offers various options for fine-tuning
18 individual RPCs.
19 \since 6.6
20
21 QGrpcCallOptions lets you customize individual remote procedure calls (RPCs).
22 The generated client interface provides access points to pass the QGrpcCallOptions.
23 These options supersede the ones set via QGrpcChannelOptions.
24
25 To configure the default options shared by RPCs, use QGrpcChannelOptions.
26*/
27
28class QGrpcCallOptionsPrivate : public QSharedData
29{
30public:
31 std::optional<std::chrono::milliseconds> timeout;
32 QHash<QByteArray, QByteArray> metadata;
33};
34
35QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QGrpcCallOptionsPrivate)
36
37/*!
38 Default-constructs an empty QGrpcCallOptions.
39*/
40QGrpcCallOptions::QGrpcCallOptions() : d_ptr(new QGrpcCallOptionsPrivate())
41{
42}
43
44/*!
45 Destroys the QGrpcCallOptions.
46*/
47QGrpcCallOptions::~QGrpcCallOptions() = default;
48
49/*!
50 Copy-constructs a QGrpcCallOptions from \a other.
51*/
52QGrpcCallOptions::QGrpcCallOptions(const QGrpcCallOptions &other) = default;
53
54/*!
55 Assigns \a other to this QGrpcCallOptions and returns a reference to the
56 updated object.
57*/
58QGrpcCallOptions &QGrpcCallOptions::operator=(const QGrpcCallOptions &other) = default;
59
60/*!
61 \fn QGrpcCallOptions::QGrpcCallOptions(QGrpcCallOptions &&other)
62
63 Move-constructs a new QGrpcCallOptions from \a other.
64
65 \include qtgrpc-shared.qdocinc move-note-desc
66*/
67
68/*!
69 \fn QGrpcCallOptions &QGrpcCallOptions::operator=(QGrpcCallOptions &&other)
70
71 Move-assigns \a other to this QGrpcCallOptions and returns a reference to
72 the updated object.
73
74 \include qtgrpc-shared.qdocinc move-note-desc
75*/
76
77/*!
78 \since 6.8
79
80 \include qtgrpc-shared.qdocinc qvariant-desc
81*/
82QGrpcCallOptions::operator QVariant() const
83{
84 return QVariant::fromValue(value: *this);
85}
86
87/*!
88 \since 6.8
89 \fn void QGrpcCallOptions::swap(QGrpcCallOptions &other)
90
91 \include qtgrpc-shared.qdocinc swap-desc
92*/
93
94/*!
95 Sets the \a timeout for a specific RPC and returns a reference to the
96 updated object.
97
98//! [set-deadline-desc]
99 A deadline sets the limit for how long a client is willing to wait for a
100 response from a server. The actual deadline is computed by adding the \a
101 timeout to the start time of the RPC.
102
103 The deadline applies to the entire lifetime of an RPC, which includes
104 receiving the final QGrpcStatus for a previously started call and can thus
105 be unwanted for (long-lived) streams.
106//! [set-deadline-desc]
107
108 \note Setting this field overrides the value set by
109 QGrpcChannelOptions::setDeadline() for a specific RPC.
110*/
111QGrpcCallOptions &QGrpcCallOptions::setDeadlineTimeout(std::chrono::milliseconds timeout)
112{
113 if (d_ptr->timeout == timeout)
114 return *this;
115 d_ptr.detach();
116 Q_D(QGrpcCallOptions);
117 d->timeout = timeout;
118 return *this;
119}
120
121/*!
122 \fn QGrpcCallOptions &QGrpcCallOptions::setMetadata(const QHash<QByteArray, QByteArray> &metadata)
123 \fn QGrpcCallOptions &QGrpcCallOptions::setMetadata(QHash<QByteArray, QByteArray> &&metadata)
124
125 Sets the client \a metadata for a specific RPC and returns a reference to the
126 updated object.
127
128//! [set-metadata-desc]
129 QGrpcHttp2Channel converts the metadata into appropriate HTTP/2 headers
130 which will be added to the HTTP/2 request.
131//! [set-metadata-desc]
132
133 \note Setting this field overrides the value set by
134 QGrpcChannelOptions::setMetadata() for a specific RPC.
135*/
136QGrpcCallOptions &QGrpcCallOptions::setMetadata(const QHash<QByteArray, QByteArray> &metadata)
137{
138 if (d_ptr->metadata == metadata)
139 return *this;
140 d_ptr.detach();
141 Q_D(QGrpcCallOptions);
142 d->metadata = metadata;
143 return *this;
144}
145
146QGrpcCallOptions &QGrpcCallOptions::setMetadata(QHash<QByteArray, QByteArray> &&metadata)
147{
148 if (d_ptr->metadata == metadata)
149 return *this;
150 d_ptr.detach();
151 Q_D(QGrpcCallOptions);
152 d->metadata = std::move(metadata);
153 return *this;
154}
155
156/*!
157 Returns the timeout duration that is used to calculate the deadline for a
158 specific RPC.
159
160 If this field is unset, returns an empty \c {std::optional}.
161*/
162std::optional<std::chrono::milliseconds> QGrpcCallOptions::deadlineTimeout() const noexcept
163{
164 Q_D(const QGrpcCallOptions);
165 return d->timeout;
166}
167
168/*!
169 \fn const QHash<QByteArray, QByteArray> &QGrpcCallOptions::metadata() const &
170 \fn QHash<QByteArray, QByteArray> QGrpcCallOptions::metadata() &&
171
172 Returns the client metadata for a specific RPC.
173 If this field is unset, returns empty metadata.
174*/
175const QHash<QByteArray, QByteArray> &QGrpcCallOptions::metadata() const & noexcept
176{
177 Q_D(const QGrpcCallOptions);
178 return d->metadata;
179}
180
181QHash<QByteArray, QByteArray> QGrpcCallOptions::metadata() &&
182{
183 Q_D(QGrpcCallOptions);
184 if (d->ref.loadRelaxed() != 1) // return copy if shared
185 return { d->metadata };
186 return std::move(d->metadata);
187}
188
189#ifndef QT_NO_DEBUG_STREAM
190/*!
191 \since 6.8
192 \fn QDebug QGrpcCallOptions::operator<<(QDebug debug, const QGrpcCallOptions &callOpts)
193
194 Writes \a callOpts to the specified stream \a debug.
195*/
196QDebug operator<<(QDebug debug, const QGrpcCallOptions &callOpts)
197{
198 const QDebugStateSaver save(debug);
199 debug.nospace().noquote();
200 debug << "QGrpcCallOptions(deadline: " << callOpts.deadlineTimeout()
201 << ", metadata: " << callOpts.metadata() << ')';
202 return debug;
203}
204#endif
205
206QT_END_NAMESPACE
207

source code of qtgrpc/src/grpc/qgrpccalloptions.cpp