cutelyst 4.0.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatorsize.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2017-2023 Matthias Fehring <mf@huessenbergnetz.de>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include "validatorsize_p.h"
7
8using namespace Cutelyst;
9
10ValidatorSize::ValidatorSize(const QString &field,
11 QMetaType::Type type,
12 const QVariant &size,
13 const Cutelyst::ValidatorMessages &messages,
14 const QString &defValKey)
15 : ValidatorRule(*new ValidatorSizePrivate(field, type, size, messages, defValKey))
16{
17}
18
20
22{
24
25 const QString v = value(params);
26
27 if (!v.isEmpty()) {
28
29 Q_D(const ValidatorSize);
30 bool ok = false;
31 bool valid = false;
32
33 switch (d->type) {
34 case QMetaType::Short:
35 case QMetaType::Int:
36 case QMetaType::Long:
37 case QMetaType::LongLong:
38 {
39 const auto val = c->locale().toLongLong(v, &ok);
40 if (Q_UNLIKELY(!ok)) {
41 result.errorMessage = parsingError(c);
42 qCWarning(C_VALIDATOR).noquote().nospace()
43 << debugString(c) << "Failed to parse \"" << v << "\" into an integer number";
44 } else {
45 const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
46 if (Q_UNLIKELY(!ok)) {
47 result.errorMessage = validationDataError(c, 1);
48 qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
49 } else {
50 if (val != size) {
51 result.errorMessage =
53 QVariantMap{{QStringLiteral("val"), val},
54 {QStringLiteral("size"), size}});
55 qCDebug(C_VALIDATOR).noquote() << debugString(c) << val << "!=" << size;
56 } else {
57 valid = true;
58 }
59 }
60 }
61 } break;
62 case QMetaType::UShort:
63 case QMetaType::UInt:
64 case QMetaType::ULong:
65 case QMetaType::ULongLong:
66 {
67 const auto val = v.toULongLong(&ok);
68 if (Q_UNLIKELY(!ok)) {
69 result.errorMessage = parsingError(c);
70 qCWarning(C_VALIDATOR).noquote().nospace()
71 << debugString(c) << "Failed to parse \"" << v
72 << "\" into an unsigned integer number";
73 } else {
74 const qulonglong size = d->extractULongLong(c, params, d->size, &ok);
75 if (Q_UNLIKELY(!ok)) {
76 result.errorMessage = validationDataError(c, 1);
77 qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
78 } else {
79 if (val != size) {
80 result.errorMessage =
82 QVariantMap{{QStringLiteral("val"), val},
83 {QStringLiteral("size"), size}});
84 qCDebug(C_VALIDATOR).noquote() << debugString(c) << val << "!=" << size;
85 } else {
86 valid = true;
87 }
88 }
89 }
90 } break;
91 case QMetaType::Float:
92 case QMetaType::Double:
93 {
94 const auto val = v.toDouble(&ok);
95 if (Q_UNLIKELY(!ok)) {
96 result.errorMessage = parsingError(c);
97 qCWarning(C_VALIDATOR).noquote().nospace()
98 << debugString(c) << "Failed to parse \"" << v
99 << "\" into a floating point number";
100 } else {
101 const double size = d->extractDouble(c, params, d->size, &ok);
102 if (Q_UNLIKELY(!ok)) {
103 result.errorMessage = validationDataError(c, 1);
104 qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
105 } else {
106 if (val != size) {
107 result.errorMessage =
109 QVariantMap{{QStringLiteral("val"), val},
110 {QStringLiteral("size"), size}});
111 qCDebug(C_VALIDATOR).noquote() << debugString(c) << val << "!=" << size;
112 } else {
113 valid = true;
114 }
115 }
116 }
117 } break;
118 case QMetaType::QString:
119 {
120 const auto val = static_cast<qlonglong>(v.length());
121 const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
122 if (Q_UNLIKELY(!ok)) {
123 result.errorMessage = validationDataError(c, 1);
124 qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
125 } else {
126 if (val != size) {
128 c,
129 QVariantMap{{QStringLiteral("val"), val}, {QStringLiteral("size"), size}});
130 qCDebug(C_VALIDATOR).noquote()
131 << debugString(c) << "string length" << val << "!=" << size;
132 } else {
133 valid = true;
134 }
135 }
136 } break;
137 default:
138 qCWarning(C_VALIDATOR).noquote()
139 << debugString(c) << "The comparison type" << d->type << "is not supported";
140 result.errorMessage = validationDataError(c, 0);
141 break;
142 }
143
144 if (valid) {
145 if (d->type != QMetaType::QString) {
146 const QVariant _v = d->valueToNumber(c, v, d->type);
147 if (_v.isValid()) {
148 result.value = _v;
149 } else {
150 result.errorMessage = parsingError(c);
151 }
152 } else {
153 result.value.setValue(v);
154 }
155 }
156 } else {
157 defaultValue(c, &result);
158 }
159
160 return result;
161}
162
163QString ValidatorSize::genericValidationError(Context *c, const QVariant &errorData) const
164{
165 QString error;
166
167 Q_D(const ValidatorSize);
168
169 const QVariantMap map = errorData.toMap();
170 QString size;
171 switch (d->type) {
172 case QMetaType::Short:
173 case QMetaType::Int:
174 case QMetaType::Long:
175 case QMetaType::LongLong:
176 case QMetaType::QString:
177 size = c->locale().toString(map.value(u"size"_qs).toLongLong());
178 break;
179 case QMetaType::UShort:
180 case QMetaType::UInt:
181 case QMetaType::ULong:
182 case QMetaType::ULongLong:
183 size = c->locale().toString(map.value(u"size"_qs).toULongLong());
184 break;
185 case QMetaType::Float:
186 case QMetaType::Double:
187 size = c->locale().toString(map.value(u"size"_qs).toDouble());
188 break;
189 default:
190 error = validationDataError(c);
191 return error;
192 }
193
194 const QString _label = label(c);
195
196 if (_label.isEmpty()) {
197 if (d->type == QMetaType::QString) {
198 //: %1 will be replaced by the required string size
199 error = c->translate("Cutelyst::ValidatorSize",
200 "The text must be exactly %1 characters long.")
201 .arg(size);
202 } else {
203 //: %1 will be replaced by the required size/value
204 error = c->translate("Cutelyst::ValidatorSize", "The value must be %1.").arg(size);
205 }
206 } else {
207 if (d->type == QMetaType::QString) {
208 //: %1 will be replaced by the field label, %2 will be replaced by the required string
209 //: size
210 error = c->translate("Cutelyst::ValidatorSize",
211 "The text in the “%1“ field must be exactly %2 characters long.")
212 .arg(_label, size);
213 } else {
214 //: %1 will be replaced by the field label, %2 will be replaced by the required
215 //: size/value
216 error =
217 c->translate("Cutelyst::ValidatorSize", "The value in the “%1” field must be %2.")
218 .arg(_label, size);
219 }
220 }
221
222 return error;
223}
224
225QString ValidatorSize::genericValidationDataError(Context *c, const QVariant &errorData) const
226{
227 QString error;
228
229 int field = errorData.toInt();
230 const QString _label = label(c);
231
232 if (field == 0) {
233 Q_D(const ValidatorSize);
234 if (_label.isEmpty()) {
235 error = c->translate("Cutelyst::ValidatorSize",
236 "The comparison type with ID %1 is not supported.")
237 .arg(static_cast<int>(d->type));
238 } else {
239 error =
240 c->translate("Cutelyst::ValidatorSize",
241 "The comparison type with ID %1 for the “%2” field is not supported.")
242 .arg(QString::number(static_cast<int>(d->type)), _label);
243 }
244 } else if (field == 1) {
245 if (_label.isEmpty()) {
246 error = c->translate("Cutelyst::ValidatorSize", "The comparison value is not valid.");
247 } else {
248 //: %1 will be replaced by the field label
249 error = c->translate("Cutelyst::ValidatorSize",
250 "The comparison value for the “%1” field is not valid.")
251 .arg(_label);
252 }
253 }
254
255 return error;
256}
257
258QString ValidatorSize::genericParsingError(Context *c, const QVariant &errorData) const
259{
260 QString error;
261 Q_UNUSED(errorData)
262 Q_D(const ValidatorSize);
263
264 const QString _label = label(c);
265 if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
266 if (_label.isEmpty()) {
267 error = c->translate("Cutelyst::ValidatorSize",
268 "Failed to parse the input value into a floating point number.");
269 } else {
270 //: %1 will be replaced by the field label
271 error = c->translate("Cutelyst::ValidatorSize",
272 "Failed to parse the input value for the “%1” field into a "
273 "floating point number.")
274 .arg(_label);
275 }
276 } else {
277 if (_label.isEmpty()) {
278 error = c->translate("Cutelyst::ValidatorSize",
279 "Failed to parse the input value into an integer number.");
280 } else {
281 //: %1 will be replaced by the field label
282 error =
283 c->translate(
284 "Cutelyst::ValidatorSize",
285 "Failed to parse the input value for the “%1” field into an integer number.")
286 .arg(_label);
287 }
288 }
289
290 return error;
291}
The Cutelyst Context.
Definition: context.h:38
QLocale locale() const noexcept
Definition: context.cpp:453
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:477
Base class for all validator rules.
QString field() const noexcept
Returns the name of the field to validate.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occurred while parsing input.
void defaultValue(Context *c, ValidatorReturnType *result) const
I a defValKey has been set in the constructor, this will try to get the default value from the stash ...
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
QString debugString(Context *c) const
Returns a string that can be used for debug output if validation fails.
The field under validation must have a size matching the given value.
Definition: validatorsize.h:48
~ValidatorSize() override
Deconstructs the size validator.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message if validation failed.
ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new size validator.
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:8
QMultiMap< QString, QString > ParamsMultiMap
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49