1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtGrpc/qgrpcchanneloptions.h>
5#include <QtGrpc/qgrpcserializationformat.h>
6#include <QtGrpc/qtgrpcnamespace.h>
7
8#include <QtCore/qbytearray.h>
9#include <QtCore/qdebug.h>
10#include <QtCore/qvariant.h>
11
12QT_BEGIN_NAMESPACE
13
14using namespace Qt::StringLiterals;
15using namespace QtGrpc;
16
17/*!
18 \class QGrpcChannelOptions
19 \inmodule QtGrpc
20 \since 6.6
21 \brief The QGrpcChannelOptions class offers various options for fine-tuning
22 a gRPC channel.
23
24 QGrpcChannelOptions lets you customize a \gRPC channel. Some options apply
25 to all remote procedure calls (RPCs) that operate on the associated
26 channel, which is used to communicate with services.
27
28 Override options for specific RPCs with QGrcCallOptions.
29
30 \note It is up to the channel's implementation to determine the specifics
31 of these options.
32*/
33
34class QGrpcChannelOptionsPrivate : public QSharedData
35{
36public:
37 std::optional<std::chrono::milliseconds> timeout;
38 QHash<QByteArray, QByteArray> metadata;
39 QGrpcSerializationFormat serializationFormat;
40#if QT_CONFIG(ssl)
41 std::optional<QSslConfiguration> sslConfiguration;
42#endif
43};
44
45QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QGrpcChannelOptionsPrivate)
46
47/*!
48 Default-constructs an empty QGrpcChannelOptions.
49*/
50QGrpcChannelOptions::QGrpcChannelOptions() : d_ptr(new QGrpcChannelOptionsPrivate())
51{
52}
53
54/*!
55 Copy-constructs a QGrpcChannelOptions from \a other.
56*/
57QGrpcChannelOptions::QGrpcChannelOptions(const QGrpcChannelOptions &other) = default;
58
59/*!
60 Assigns \a other to this QGrpcChannelOptions and returns a reference to the
61 updated object.
62*/
63QGrpcChannelOptions &QGrpcChannelOptions::operator=(const QGrpcChannelOptions &other) = default;
64
65/*!
66 \fn QGrpcChannelOptions::QGrpcChannelOptions(QGrpcChannelOptions &&other)
67
68 Move-constructs a new QGrpcChannelOptions from \a other.
69
70 \include qtgrpc-shared.qdocinc move-note-desc
71*/
72
73/*!
74 \fn QGrpcChannelOptions &QGrpcChannelOptions::operator=(QGrpcChannelOptions &&other)
75
76 Move-assigns \a other to this QGrpcChannelOptions and returns a reference
77 to the updated object.
78
79 \include qtgrpc-shared.qdocinc move-note-desc
80*/
81
82/*!
83 \since 6.8
84 \fn void QGrpcChannelOptions::swap(QGrpcChannelOptions &other)
85
86 \include qtgrpc-shared.qdocinc swap-desc
87*/
88
89/*!
90 Destroys the QGrpcChannelOptions.
91*/
92QGrpcChannelOptions::~QGrpcChannelOptions() = default;
93
94/*!
95 \since 6.8
96 \include qtgrpc-shared.qdocinc qvariant-desc
97*/
98QGrpcChannelOptions::operator QVariant() const
99{
100 return QVariant::fromValue(value: *this);
101}
102
103/*!
104 Sets the \a timeout for the channel and returns a reference to the updated
105 object.
106
107 \include qgrpccalloptions.cpp set-deadline-desc
108
109 \note The deadline set via the channel options applies to all RPCs that
110 operate on the channel, except those overridden by
111 QGrpcCallOptions::setDeadline().
112*/
113QGrpcChannelOptions &QGrpcChannelOptions::setDeadlineTimeout(std::chrono::milliseconds timeout)
114{
115 if (d_ptr->timeout == timeout)
116 return *this;
117 d_ptr.detach();
118 Q_D(QGrpcChannelOptions);
119 d->timeout = timeout;
120 return *this;
121}
122
123/*!
124 \fn QGrpcChannelOptions &QGrpcChannelOptions::setMetadata(const QHash<QByteArray, QByteArray> &metadata)
125 \fn QGrpcChannelOptions &QGrpcChannelOptions::setMetadata(QHash<QByteArray, QByteArray> &&metadata)
126
127 Sets the client \a metadata for the channel and returns a reference to the
128 updated object.
129
130 \include qgrpccalloptions.cpp set-metadata-desc
131
132 \note The metadata set via the channel options applies to all RPCs that
133 operate on the channel, except those overridden by
134 QGrpcCallOptions::setMetadata().
135*/
136QGrpcChannelOptions &QGrpcChannelOptions::setMetadata(const QHash<QByteArray, QByteArray> &metadata)
137{
138 if (d_ptr->metadata == metadata)
139 return *this;
140 d_ptr.detach();
141 Q_D(QGrpcChannelOptions);
142 d->metadata = metadata;
143 return *this;
144}
145
146QGrpcChannelOptions &QGrpcChannelOptions::setMetadata(QHash<QByteArray, QByteArray> &&metadata)
147{
148 if (d_ptr->metadata == metadata)
149 return *this;
150 d_ptr.detach();
151 Q_D(QGrpcChannelOptions);
152 d->metadata = std::move(metadata);
153 return *this;
154}
155
156/*!
157 \since 6.8
158
159 Sets the serialization \a format for the channel and returns a reference to
160 the updated object.
161*/
162QGrpcChannelOptions &
163QGrpcChannelOptions::setSerializationFormat(const QGrpcSerializationFormat &format)
164{
165 if (d_ptr->serializationFormat == format)
166 return *this;
167 d_ptr.detach();
168 Q_D(QGrpcChannelOptions);
169 d->serializationFormat = format;
170 return *this;
171}
172
173/*!
174 Returns the timeout duration that is used to calculate the deadline for the
175 channel.
176
177 If this field is unset, returns an empty \c {std::optional}.
178*/
179std::optional<std::chrono::milliseconds> QGrpcChannelOptions::deadlineTimeout() const noexcept
180{
181 Q_D(const QGrpcChannelOptions);
182 return d->timeout;
183}
184
185/*!
186 \fn const QHash<QByteArray, QByteArray> &QGrpcChannelOptions::metadata() const &
187 \fn QHash<QByteArray, QByteArray> QGrpcChannelOptions::metadata() &&
188
189 Returns the client metadata for the channel.
190
191 If this field is unset, returns empty metadata.
192*/
193const QHash<QByteArray, QByteArray> &QGrpcChannelOptions::metadata() const & noexcept
194{
195 Q_D(const QGrpcChannelOptions);
196 return d->metadata;
197}
198
199QHash<QByteArray, QByteArray> QGrpcChannelOptions::metadata() &&
200{
201 Q_D(QGrpcChannelOptions);
202 if (d->ref.loadRelaxed() != 1) // return copy if shared
203 return { d->metadata };
204 return std::move(d->metadata);
205}
206
207/*!
208 \since 6.8
209
210 Returns the serialization format used by the channel.
211
212 If this field is unset, returns a \l {QtGrpc::SerializationFormat::}
213 {Default} constructed serialization format.
214 */
215QGrpcSerializationFormat QGrpcChannelOptions::serializationFormat() const
216{
217 Q_D(const QGrpcChannelOptions);
218 return d->serializationFormat;
219}
220
221#if QT_CONFIG(ssl)
222/*!
223 Sets the \a sslConfiguration for the channel and returns a reference to the
224 updated object.
225*/
226QGrpcChannelOptions &
227QGrpcChannelOptions::setSslConfiguration(const QSslConfiguration &sslConfiguration)
228{
229 if (d_ptr->sslConfiguration == sslConfiguration)
230 return *this;
231 d_ptr.detach();
232 Q_D(QGrpcChannelOptions);
233 d->sslConfiguration = sslConfiguration;
234 return *this;
235}
236
237/*!
238 Returns the SSL configuration for the channel.
239
240 If this field is unset, returns an empty \c {std::optional}.
241*/
242std::optional<QSslConfiguration> QGrpcChannelOptions::sslConfiguration() const
243{
244 Q_D(const QGrpcChannelOptions);
245 return d->sslConfiguration;
246}
247#endif
248
249#ifndef QT_NO_DEBUG_STREAM
250/*!
251 \since 6.8
252 \fn QDebug QGrpcChannelOptions::operator<<(QDebug debug, const QGrpcChannelOptions &chOpts)
253
254 Writes \a chOpts to the specified stream \a debug.
255*/
256QDebug operator<<(QDebug debug, const QGrpcChannelOptions &chOpts)
257{
258 const QDebugStateSaver save(debug);
259 debug.nospace().noquote();
260 debug << "QGrpcChannelOptions(deadline: " << chOpts.deadlineTimeout()
261 << ", metadata: " << chOpts.metadata()
262 << ", serializationFormat: " << chOpts.serializationFormat().suffix()
263 << ", sslConfiguration: ";
264# if QT_CONFIG(ssl)
265 if (chOpts.sslConfiguration())
266 debug << "available";
267 else
268 debug << std::nullopt;
269# else
270 debug << "unsupported";
271# endif
272 debug << ')';
273 return debug;
274}
275#endif
276
277QT_END_NAMESPACE
278

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