cutelyst  3.9.1
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-2022 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatorsize_p.h"
7 
8 using namespace Cutelyst;
9 
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 {
21 }
22 
24 {
25  ValidatorReturnType result;
26 
27  const QString v = value(params);
28 
29  if (!v.isEmpty()) {
30 
31  Q_D(const ValidatorSize);
32  bool ok = false;
33  bool valid = false;
34 
35  switch (d->type) {
36  case QMetaType::Short:
37  case QMetaType::Int:
38  case QMetaType::Long:
40  {
41  const qlonglong val = c->locale().toLongLong(v, &ok);
42  if (Q_UNLIKELY(!ok)) {
43  result.errorMessage = parsingError(c);
44  qCWarning(C_VALIDATOR,
45  "ValidatorSize: Failed to parse value of field %s into number at %s::%s.",
46  qPrintable(field()),
47  qPrintable(c->controllerName()),
48  qPrintable(c->actionName()));
49  } else {
50  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
51  if (Q_UNLIKELY(!ok)) {
52  result.errorMessage = validationDataError(c, 1);
53  qCWarning(C_VALIDATOR,
54  "ValidatorSize: Invalid comparison size for field %s in %s::%s.",
55  qPrintable(field()),
56  qPrintable(c->controllerName()),
57  qPrintable(c->actionName()));
58  } else {
59  if (val != size) {
60  result.errorMessage =
62  QVariantMap{{QStringLiteral("val"), val},
63  {QStringLiteral("size"), size}});
64  qCDebug(C_VALIDATOR,
65  "ValidatorSize: Validation failed for field %s in %s::%s: value is "
66  "not %lli.",
67  qPrintable(field()),
68  qPrintable(c->controllerName()),
69  qPrintable(c->actionName()),
70  size);
71  } else {
72  valid = true;
73  }
74  }
75  }
76  } break;
77  case QMetaType::UShort:
78  case QMetaType::UInt:
79  case QMetaType::ULong:
81  {
82  const qulonglong val = v.toULongLong(&ok);
83  if (Q_UNLIKELY(!ok)) {
84  result.errorMessage = parsingError(c);
85  qCWarning(C_VALIDATOR,
86  "ValidatorSize: Failed to parse value of field %s into number at %s::%s.",
87  qPrintable(field()),
88  qPrintable(c->controllerName()),
89  qPrintable(c->actionName()));
90  } else {
91  const qulonglong size = d->extractULongLong(c, params, d->size, &ok);
92  if (Q_UNLIKELY(!ok)) {
93  result.errorMessage = validationDataError(c, 1);
94  qCWarning(
95  C_VALIDATOR,
96  "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.",
97  qPrintable(field()),
98  qPrintable(c->controllerName()),
99  qPrintable(c->actionName()));
100  } else {
101  if (val != size) {
102  result.errorMessage =
103  validationError(c,
104  QVariantMap{{QStringLiteral("val"), val},
105  {QStringLiteral("size"), size}});
106  qCDebug(C_VALIDATOR,
107  "ValidatorSize: Validation failed for field %s in %s::%s: value is "
108  "not %llu.",
109  qPrintable(field()),
110  qPrintable(c->controllerName()),
111  qPrintable(c->actionName()),
112  size);
113  } else {
114  valid = true;
115  }
116  }
117  }
118  } break;
119  case QMetaType::Float:
120  case QMetaType::Double:
121  {
122  const double val = v.toDouble(&ok);
123  if (Q_UNLIKELY(!ok)) {
124  result.errorMessage = parsingError(c);
125  qCWarning(C_VALIDATOR,
126  "ValidatorSize: Failed to parse value of field %s into number at %s::%s.",
127  qPrintable(field()),
128  qPrintable(c->controllerName()),
129  qPrintable(c->actionName()));
130  } else {
131  const double size = d->extractDouble(c, params, d->size, &ok);
132  if (Q_UNLIKELY(!ok)) {
133  result.errorMessage = validationDataError(c, 1);
134  qCWarning(
135  C_VALIDATOR,
136  "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.",
137  qPrintable(field()),
138  qPrintable(c->controllerName()),
139  qPrintable(c->actionName()));
140  } else {
141  if (val != size) {
142  result.errorMessage =
143  validationError(c,
144  QVariantMap{{QStringLiteral("val"), val},
145  {QStringLiteral("size"), size}});
146  qCDebug(C_VALIDATOR,
147  "ValidatorSize: Validation failed for field %s in %s::%s: value is "
148  "not %f.",
149  qPrintable(field()),
150  qPrintable(c->controllerName()),
151  qPrintable(c->actionName()),
152  size);
153  } else {
154  valid = true;
155  }
156  }
157  }
158  } break;
159  case QMetaType::QString:
160  {
161  const qlonglong val = static_cast<qlonglong>(v.length());
162  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
163  if (Q_UNLIKELY(!ok)) {
164  result.errorMessage = validationDataError(c, 1);
165  qCWarning(C_VALIDATOR,
166  "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.",
167  qPrintable(field()),
168  qPrintable(c->controllerName()),
169  qPrintable(c->actionName()));
170  } else {
171  if (val != size) {
172  result.errorMessage = validationError(
173  c,
174  QVariantMap{{QStringLiteral("val"), val}, {QStringLiteral("size"), size}});
175  qCDebug(C_VALIDATOR,
176  "ValidatorSize: Validation failed for field %s in %s::%s: string "
177  "length is not %lli.",
178  qPrintable(field()),
179  qPrintable(c->controllerName()),
180  qPrintable(c->actionName()),
181  size);
182  } else {
183  valid = true;
184  }
185  }
186  } break;
187  default:
188  qCWarning(C_VALIDATOR,
189  "ValidatorSize: The comparison type with ID %i for field %s at %s::%s is not "
190  "supported.",
191  static_cast<int>(d->type),
192  qPrintable(field()),
193  qPrintable(c->controllerName()),
194  qPrintable(c->actionName()));
195  result.errorMessage = validationDataError(c, 0);
196  break;
197  }
198 
199  if (valid) {
200  if (d->type != QMetaType::QString) {
201  const QVariant _v = d->valueToNumber(c, v, d->type);
202  if (_v.isValid()) {
203  result.value = _v;
204  } else {
205  result.errorMessage = parsingError(c);
206  }
207  } else {
208  result.value.setValue(v);
209  }
210  }
211  } else {
212  defaultValue(c, &result, "ValidatorSize");
213  }
214 
215  return result;
216 }
217 
219 {
220  QString error;
221 
222  Q_D(const ValidatorSize);
223 
224  const QVariantMap map = errorData.toMap();
225  QString size;
226  switch (d->type) {
227  case QMetaType::Short:
228  case QMetaType::Int:
229  case QMetaType::Long:
230  case QMetaType::LongLong:
231  case QMetaType::QString:
232  size = c->locale().toString(map.value(QStringLiteral("size")).toLongLong());
233  break;
234  case QMetaType::UShort:
235  case QMetaType::UInt:
236  case QMetaType::ULong:
238  size = c->locale().toString(map.value(QStringLiteral("size")).toULongLong());
239  break;
240  case QMetaType::Float:
241  case QMetaType::Double:
242  size = c->locale().toString(map.value(QStringLiteral("size")).toDouble());
243  break;
244  default:
245  error = validationDataError(c);
246  return error;
247  }
248 
249  const QString _label = label(c);
250 
251  if (_label.isEmpty()) {
252  if (d->type == QMetaType::QString) {
253  //: %1 will be replaced by the required string size
254  error = c->translate("Cutelyst::ValidatorSize",
255  "The text must be exactly %1 characters long.")
256  .arg(size);
257  } else {
258  //: %1 will be replaced by the required size/value
259  error = c->translate("Cutelyst::ValidatorSize", "The value must be %1.").arg(size);
260  }
261  } else {
262  if (d->type == QMetaType::QString) {
263  //: %1 will be replaced by the field label, %2 will be replaced by the required string
264  //: size
265  error = c->translate("Cutelyst::ValidatorSize",
266  "The text in the “%1“ field must be exactly %2 characters long.")
267  .arg(_label, size);
268  } else {
269  //: %1 will be replaced by the field label, %2 will be replaced by the required
270  //: size/value
271  error =
272  c->translate("Cutelyst::ValidatorSize", "The value in the “%1” field must be %2.")
273  .arg(_label, size);
274  }
275  }
276 
277  return error;
278 }
279 
281 {
282  QString error;
283 
284  int field = errorData.toInt();
285  const QString _label = label(c);
286 
287  if (field == 0) {
288  Q_D(const ValidatorSize);
289  if (_label.isEmpty()) {
290  error = c->translate("Cutelyst::ValidatorSize",
291  "The comparison type with ID %1 is not supported.")
292  .arg(static_cast<int>(d->type));
293  } else {
294  error =
295  c->translate("Cutelyst::ValidatorSize",
296  "The comparison type with ID %1 for the “%2” field is not supported.")
297  .arg(QString::number(static_cast<int>(d->type)), _label);
298  }
299  } else if (field == 1) {
300  if (_label.isEmpty()) {
301  error = c->translate("Cutelyst::ValidatorSize", "The comparison value is not valid.");
302  } else {
303  //: %1 will be replaced by the field label
304  error = c->translate("Cutelyst::ValidatorSize",
305  "The comparison value for the “%1” field is not valid.")
306  .arg(_label);
307  }
308  }
309 
310  return error;
311 }
312 
314 {
315  QString error;
316  Q_UNUSED(errorData)
317  Q_D(const ValidatorSize);
318 
319  const QString _label = label(c);
320  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
321  if (_label.isEmpty()) {
322  error = c->translate("Cutelyst::ValidatorSize",
323  "Failed to parse the input value into a floating point number.");
324  } else {
325  //: %1 will be replaced by the field label
326  error = c->translate("Cutelyst::ValidatorSize",
327  "Failed to parse the input value for the “%1” field into a "
328  "floating point number.")
329  .arg(_label);
330  }
331  } else {
332  if (_label.isEmpty()) {
333  error = c->translate("Cutelyst::ValidatorSize",
334  "Failed to parse the input value into an integer number.");
335  } else {
336  //: %1 will be replaced by the field label
337  error =
338  c->translate(
339  "Cutelyst::ValidatorSize",
340  "Failed to parse the input value for the “%1” field into an integer number.")
341  .arg(_label);
342  }
343  }
344 
345  return error;
346 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message if validation failed.
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occurred while parsing input.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
qlonglong toLongLong(QStringView s, bool *ok) const const
Stores custom error messages and the input field label.
size_type size() const const
double toDouble(bool *ok) const const
QString toString(QDate date, FormatType format) const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
The field under validation must have a size matching the given value.
Definition: validatorsize.h:47
The Cutelyst Context.
Definition: context.h:38
QString number(double n, char format, int precision)
int toInt(bool *ok) const const
~ValidatorSize() override
Deconstructs the size validator.
bool isEmpty() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:490
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
Base class for all validator rules.
qulonglong toULongLong(bool *ok, int base) const const
QLocale locale() const noexcept
Definition: context.cpp:466
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
QMap< QString, QVariant > toMap() const const
qsizetype length() const const
QString field() const
Returns the name of the field to validate.
bool isValid() const const
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49
ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new size validator.
QString arg(Args &&... args) const const
void defaultValue(Context *c, ValidatorReturnType *result, const char *validatorName) const
I a defValKey has been set in the constructor, this will try to get the default value from the stash ...
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.
void setValue(QVariant &&value)