Smithy Qt 0.1.0-pre
Internal development documentation
Loading...
Searching...
No Matches
shapeid.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2013-2025 Paul Colby <git@colby.id.au>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4/*!
5 * \file
6 * Defines the ShapeId and ShapeIdPrivate classes.
7 */
8
9#include <qtsmithy/shapeid.h>
10#include "shapeid_p.h"
11
12#include <QRegularExpression>
13
15
16/*!
17 * \class ShapeId
18 *
19 * The ShapeId class provides a Qt representation of a Smithy Shape ID.
20 *
21 * \see https://awslabs.github.io/smithy/2.0/spec/model.html#shape-id
22 */
23
24/*!
25 * Constructs an empty ShapeId object.
26 */
28{
29
30}
31
32/*!
33 * Constructs a ShapeId object by moving resources from \a other.
34 */
36{
37 Q_D(ShapeId);
38 d->memberName = std::move(other.d_ptr->memberName);
39 d->nameSpace = std::move(other.d_ptr->nameSpace);
40 d->shapeName = std::move(other.d_ptr->shapeName);
41}
42
43/*!
44 * Constructs a ShapeId object by copying \a other.
45 */
46ShapeId::ShapeId(const ShapeId &other) : d_ptr(new ShapeIdPrivate(this))
47{
48 Q_D(ShapeId);
49 d->memberName = other.d_ptr->memberName;
50 d->nameSpace = other.d_ptr->nameSpace;
51 d->shapeName = other.d_ptr->shapeName;
52}
53
54/*!
55 * Constructs a ShapeId object by parsing the Smithy Shape ID given by \a shapeId.
56 *
57 * To be considered valid, \a shapeId must contain at least a valid shape name, but may also contain
58 * optional namespace and member name components. Use isValid() to verify \a shapeId's validity.
59 *
60 * \see isValid
61 * \see https://awslabs.github.io/smithy/2.0/spec/model.html#shape-id
62 */
63ShapeId::ShapeId(const QString &shapeId) : d_ptr(new ShapeIdPrivate(this))
64{
65 Q_D(ShapeId);
66 d->setShapeId(shapeId);
67}
68
69/*!
70 * Assigns the specified \a shapeId to this object.
71 */
73{
74 Q_D(ShapeId);
75 d->memberName = shapeId.d_ptr->memberName;
76 d->nameSpace = shapeId.d_ptr->nameSpace;
77 d->shapeName = shapeId.d_ptr->shapeName;
78 return *this;
79}
80
81/*!
82 * Moves the specified \a shapeId to this object.
83 */
85{
86 Q_D(ShapeId);
87 d->memberName = std::move(shapeId.d_ptr->memberName);
88 d->nameSpace = std::move(shapeId.d_ptr->nameSpace);
89 d->shapeName = std::move(shapeId.d_ptr->shapeName);
90 return *this;
91}
92
93/*!
94 * Assigns the specified \a shapeId to this object.
95 */
96ShapeId& ShapeId::operator=(const QString &shapeId)
97{
98 Q_D(ShapeId);
99 d->setShapeId(shapeId);
100 return *this;
101}
102
103/*!
104 * Destroys this ShapeId object.
105 */
107{
108 delete d_ptr;
109}
110
111/*!
112 * Returns the Shape ID's member name, if it has one, otherwise a null string.
113 */
114QString ShapeId::memberName() const
115{
116 Q_D(const ShapeId);
117 return d->memberName;
118}
119
120/*!
121 * Returns the Shape ID's namespace, if it has one, otherwise a null string.
122 */
123QString ShapeId::nameSpace() const
124{
125 Q_D(const ShapeId);
126 return d->nameSpace;
127}
128
129/*!
130 * Returns the Shape ID's shape name, if it has one, otherwise a null string.
131 *
132 * Note, a Shape ID is considered invalid if it has no shape name.
133 *
134 * \see isValid
135 */
136QString ShapeId::shapeName() const
137{
138 Q_D(const ShapeId);
139 return d->shapeName;
140}
141
142/*!
143 * Set the Shape ID's member name to \a name, which may be an empty or null string.
144 */
145void ShapeId::setMemberName(const QString &name)
146{
147 Q_D(ShapeId);
148 d->memberName = name;
149}
150
151/*!
152 * Set the Shape ID's namespace to \a name, which may be an empty or null string.
153 */
154void ShapeId::setNameSpace(const QString &name)
155{
156 Q_D(ShapeId);
157 d->nameSpace = name;
158}
159
160/*!
161 * Set the Shape ID's shape name to \a name.
162 *
163 * Note, a Shape ID is considered invalid if it has no shape name, so \a name should typically be
164 * non-empty.
165 */
166void ShapeId::setShapeName(const QString &name)
167{
168 Q_D(ShapeId);
169 d->shapeName = name;
170}
171
172/*!
173 * Returns this object as an absolute Smithy Shape ID if this object has a namespace, otherwise a
174 * null string.
175 *
176 * \note, Smithy defines an absolute Shape ID as one that begins with a namespace, therefore it is
177 * not possible to return an absolute Shape ID if no namespace has been set.
178 *
179 * \note, if the Shape ID is invalid (ie isValid() returns \c false) it still safe to invoke this
180 * method, but the result is undefined.
181 *
182 * \see setNameSpace
183 * \see isValid
184 */
186{
187 return hasNameSpace() ? QStringLiteral("%1#%2").arg(nameSpace(), relativeShapeId()) : QString();
188}
189
190/*!
191 * Returns this object as a relative Smithy Shape ID, that one without a leading namespace.
192 *
193 * \note, if the Shape ID is invalid (ie isValid() returns \c false) it still safe to invoke this
194 * method, but the result is undefined.
195 *
196 * \see isValid
197 */
199{
200 return hasMemberName() ? QStringLiteral("%1$%2").arg(shapeName(), memberName()) : shapeName();
201}
202
203/*!
204 * Returns this object as an *absolute* Smithy Shape ID if this object has a namespace, otherwise a
205 * *relative* Smithy Shape ID.
206 *
207 * \note, if the Shape ID is invalid (ie isValid() returns \c false) it still safe to invoke this
208 * method, but the result is undefined.
209 *
210 * \see absoluteShapeId
211 * \see relativeShapeId
212 * \see isValid
213 */
214QString ShapeId::toString() const
215{
217}
218
219/*!
220 * Returns \c true if this Shape ID has a non-empty namespace, otherwise \c false otherwise.
221 *
222 * \see nameSpace.
223 * \see setNameSpace.
224 */
226{
227 return !nameSpace().isEmpty();
228}
229
230/*!
231 * Returns \c true if this Shape ID has a non-empty member name, otherwise \c false otherwise.
232 *
233 * \see memberName.
234 * \see setMemberName.
235 */
237{
238 return !memberName().isEmpty();
239}
240
241/*!
242 * Returns \c true if this Shape ID is a *root* Shape ID, and has a namespace, \c false otherwise.
243 *
244 * \see isRootShapeId.
245 * \see hasNameSpace.
246 */
248{
249 return isRootShapeId() && hasNameSpace();
250}
251
252/*!
253 * Returns \c true if this Shape ID is a *root* Shape ID, \c false otherwise.
254 *
255 * \note, Smithy defines a root Shape ID as one that does not have a member name.
256 *
257 * \see hasMemberName.
258 */
260{
261 return !hasMemberName();
262}
263
264/*!
265 * Returns \c true if this Shape ID is a *relative* Shape ID, \c false otherwise.
266 *
267 * \note, Smithy defines a relative Shape ID as one that does not have a namespace.
268 *
269 * \see hasNameSpace.
270 */
272{
273 return !hasNameSpace();
274}
275
276/*!
277 * Returns true if this object represents a valid, non-empty Smithy Shape ID.
278 *
279 * \see https://awslabs.github.io/smithy/2.0/spec/model.html#shape-id
280 */
282{
283 Q_D(const ShapeId);
284 // Validate the (optional) namespace.
285 if (!d->nameSpace.isEmpty()) {
286 static QRegularExpression namespacePattern(QStringLiteral("^(_*[a-zA-Z]\\w*\\.?)+(?<!\\.)$"));
287 Q_ASSERT(namespacePattern.isValid());
288 if (!namespacePattern.match(d->nameSpace).hasMatch()) {
289 return false;
290 }
291 }
292
293 // Validate the (required) shape name.
294 static QRegularExpression identifierPattern(QStringLiteral("^_*[a-zA-Z]\\w*$"));
295 Q_ASSERT(identifierPattern.isValid());
296 if ((d->shapeName.isEmpty()) || (!identifierPattern.match(d->shapeName).hasMatch())) {
297 return false;
298 }
299
300 // Validate the (optional) member name.
301 if ((!d->memberName.isEmpty()) && (!identifierPattern.match(d->memberName).hasMatch())) {
302 return false;
303 }
304 return true; // Valid.
305}
306
307bool ShapeId::operator==(const ShapeId &other) const
308{
309 Q_D(const ShapeId);
310 return (d->memberName == other.d_ptr->memberName) &&
311 (d->nameSpace == other.d_ptr->nameSpace) &&
312 (d->shapeName == other.d_ptr->shapeName);
313}
314
315#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
316uint qHash(const ShapeId &key, uint seed)
317#else
318size_t qHash(const ShapeId &key, size_t seed)
319#endif
320{
321 return ::qHash(key.toString(), seed);
322}
323
324/*!
325 * \cond internal
326 * \class ShapeIdPrivate
327 *
328 * The ShapeIdPrivate class provides private implementation for ShapeId.
329 */
330
331/*!
332 * \internal
333 * Constructs a new ShapeIdPrivate object with public implementation \a q.
334 */
336{
337
338}
339
340/*!
341 * Splits \a shapeId into its components (namespace, shape name and member name) and assigns them
342 * to the equivalent object members.
343 *
344 * Both the namespace and member name are optional; their equivalent object members will be set to
345 * empty strings if not present in \a shapeId.
346 */
347void ShapeIdPrivate::setShapeId(const QString &shapeId)
348{
349 const int sep1 = shapeId.indexOf(QLatin1Char('#'));
350 const int sep2 = shapeId.lastIndexOf(QLatin1Char('$'));
351 if (sep1 > 0) nameSpace = shapeId.mid(0, sep1);
352 if (sep2 > 0) memberName = shapeId.mid(sep2+1);
353 shapeName = shapeId.mid(sep1+1, sep2-sep1-1);
354}
355
356/// \endcond
357
The ShapeIdPrivate class provides private implementation for ShapeId.
Definition shapeid_p.h:20
ShapeId * q_ptr
Internal q-pointer.
Definition shapeid_p.h:29
ShapeIdPrivate(ShapeId *const q)
Definition shapeid.cpp:335
void setShapeId(const QString &shapeId)
Splits shapeId into its components (namespace, shape name and member name) and assigns them to the eq...
Definition shapeid.cpp:347
The ShapeId class provides a Qt representation of a Smithy Shape ID.
Definition shapeid.h:29
QString nameSpace() const
Returns the Shape ID's namespace, if it has one, otherwise a null string.
Definition shapeid.cpp:123
bool isValid() const
Returns true if this object represents a valid, non-empty Smithy Shape ID.
Definition shapeid.cpp:281
void setMemberName(const QString &name)
Set the Shape ID's member name to name, which may be an empty or null string.
Definition shapeid.cpp:145
QString absoluteShapeId() const
Returns this object as an absolute Smithy Shape ID if this object has a namespace,...
Definition shapeid.cpp:185
~ShapeId()
Destroys this ShapeId object.
Definition shapeid.cpp:106
QString toString() const
Returns this object as an absolute Smithy Shape ID if this object has a namespace,...
Definition shapeid.cpp:214
ShapeId()
Constructs an empty ShapeId object.
Definition shapeid.cpp:27
ShapeId & operator=(const ShapeId &shapeId)
Assigns the specified shapeId to this object.
Definition shapeid.cpp:72
bool isRootShapeId() const
Returns true if this Shape ID is a root Shape ID, false otherwise.
Definition shapeid.cpp:259
bool hasMemberName() const
Returns true if this Shape ID has a non-empty member name, otherwise false otherwise.
Definition shapeid.cpp:236
QString shapeName() const
Returns the Shape ID's shape name, if it has one, otherwise a null string.
Definition shapeid.cpp:136
void setNameSpace(const QString &name)
Set the Shape ID's namespace to name, which may be an empty or null string.
Definition shapeid.cpp:154
QString memberName() const
Returns the Shape ID's member name, if it has one, otherwise a null string.
Definition shapeid.cpp:114
QString relativeShapeId() const
Returns this object as a relative Smithy Shape ID, that one without a leading namespace.
Definition shapeid.cpp:198
bool hasNameSpace() const
Returns true if this Shape ID has a non-empty namespace, otherwise false otherwise.
Definition shapeid.cpp:225
ShapeIdPrivate * d_ptr
Definition shapeid.h:65
void setShapeName(const QString &name)
Set the Shape ID's shape name to name.
Definition shapeid.cpp:166
bool isAbsoluteRootShapeId() const
Returns true if this Shape ID is a root Shape ID, and has a namespace, false otherwise.
Definition shapeid.cpp:247
bool isRelativeShapeId() const
Returns true if this Shape ID is a relative Shape ID, false otherwise.
Definition shapeid.cpp:271
#define QTSMITHY_BEGIN_NAMESPACE
Macro for starting the QtSmithy library's top-most namespace (if one is defined).
#define QTSMITHY_END_NAMESPACE
Macro for ending the QtSmithy library's top-most namespace (if one is defined).
Declares the ShapeId class.
Declares the ShapeIdPrivate class.