Cutelyst  3.7.0
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 
10 ValidatorSize::ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
11  ValidatorRule(*new ValidatorSizePrivate(field, type, size, messages, defValKey))
12 {
13 }
14 
16 {
17 }
18 
20 {
21  ValidatorReturnType result;
22 
23  const QString v = value(params);
24 
25  if (!v.isEmpty()) {
26 
27  Q_D(const ValidatorSize);
28  bool ok = false;
29  bool valid = false;
30 
31  switch (d->type) {
32  case QMetaType::Short:
33  case QMetaType::Int:
34  case QMetaType::Long:
36  {
37  const qlonglong val = c->locale().toLongLong(v, &ok);
38  if (Q_UNLIKELY(!ok)) {
39  result.errorMessage = parsingError(c);
40  qCWarning(C_VALIDATOR, "ValidatorSize: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
41  } else {
42  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
43  if (Q_UNLIKELY(!ok)) {
44  result.errorMessage = validationDataError(c, 1);
45  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid comparison size for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
46  } else {
47  if (val != size) {
48  result.errorMessage = validationError(c, QVariantMap{
49  {QStringLiteral("val"), val},
50  {QStringLiteral("size"), size}
51  });
52  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: value is not %lli.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
53  } else {
54  valid = true;
55  }
56  }
57  }
58  }
59  break;
60  case QMetaType::UShort:
61  case QMetaType::UInt:
62  case QMetaType::ULong:
64  {
65  const qulonglong val = v.toULongLong(&ok);
66  if (Q_UNLIKELY(!ok)) {
67  result.errorMessage = parsingError(c);
68  qCWarning(C_VALIDATOR, "ValidatorSize: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
69  } else {
70  const qulonglong size = d->extractULongLong(c, params, d->size, &ok);
71  if (Q_UNLIKELY(!ok)) {
72  result.errorMessage = validationDataError(c, 1);
73  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
74  } else {
75  if (val != size) {
76  result.errorMessage = validationError(c, QVariantMap{
77  {QStringLiteral("val"), val},
78  {QStringLiteral("size"), size}
79  });
80  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: value is not %llu.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
81  } else {
82  valid = true;
83  }
84  }
85  }
86  }
87  break;
88  case QMetaType::Float:
89  case QMetaType::Double:
90  {
91  const double val = v.toDouble(&ok);
92  if (Q_UNLIKELY(!ok)) {
93  result.errorMessage = parsingError(c);
94  qCWarning(C_VALIDATOR, "ValidatorSize: Failed to parse value of field %s into number at %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
95  } else {
96  const double size = d->extractDouble(c, params, d->size, &ok);
97  if (Q_UNLIKELY(!ok)) {
98  result.errorMessage = validationDataError(c, 1);
99  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
100  } else {
101  if (val != size) {
102  result.errorMessage = validationError(c, QVariantMap{
103  {QStringLiteral("val"), val},
104  {QStringLiteral("size"), size}
105  });
106  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: value is not %f.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
107  } else {
108  valid = true;
109  }
110  }
111  }
112  }
113  break;
114  case QMetaType::QString:
115  {
116  const qlonglong val = static_cast<qlonglong>(v.length());
117  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
118  if (Q_UNLIKELY(!ok)) {
119  result.errorMessage = validationDataError(c, 1);
120  qCWarning(C_VALIDATOR, "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
121  } else {
122  if (val != size) {
123  result.errorMessage = validationError(c, QVariantMap{
124  {QStringLiteral("val"), val},
125  {QStringLiteral("size"), size}
126  });
127  qCDebug(C_VALIDATOR, "ValidatorSize: Validation failed for field %s in %s::%s: string length is not %lli.", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()), size);
128  } else {
129  valid = true;
130  }
131  }
132  }
133  break;
134  default:
135  qCWarning(C_VALIDATOR, "ValidatorSize: The comparison type with ID %i for field %s at %s::%s is not supported.", static_cast<int>(d->type), qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
136  result.errorMessage = validationDataError(c, 0);
137  break;
138  }
139 
140  if (valid) {
141  if (d->type != QMetaType::QString) {
142  const QVariant _v = d->valueToNumber(c, v, d->type);
143  if (_v.isValid()) {
144  result.value = _v;
145  } else {
146  result.errorMessage = parsingError(c);
147  }
148  } else {
149  result.value.setValue(v);
150  }
151  }
152  } else {
153  defaultValue(c, &result, "ValidatorSize");
154  }
155 
156  return result;
157 }
158 
160 {
161  QString error;
162 
163  Q_D(const ValidatorSize);
164 
165  const QVariantMap map = errorData.toMap();
166  QString size;
167  switch (d->type) {
168  case QMetaType::Short:
169  case QMetaType::Int:
170  case QMetaType::Long:
171  case QMetaType::LongLong:
172  case QMetaType::QString:
173  size = c->locale().toString(map.value(QStringLiteral("size")).toLongLong());
174  break;
175  case QMetaType::UShort:
176  case QMetaType::UInt:
177  case QMetaType::ULong:
179  size = c->locale().toString(map.value(QStringLiteral("size")).toULongLong());
180  break;
181  case QMetaType::Float:
182  case QMetaType::Double:
183  size = c->locale().toString(map.value(QStringLiteral("size")).toDouble());
184  break;
185  default:
186  error = validationDataError(c);
187  return error;
188  }
189 
190  const QString _label = label(c);
191 
192  if (_label.isEmpty()) {
193  if (d->type == QMetaType::QString) {
194  //: %1 will be replaced by the required string size
195  error = c->translate("Cutelyst::ValidatorSize", "The text must be exactly %1 characters long.").arg(size);
196  } else {
197  //: %1 will be replaced by the required size/value
198  error = c->translate("Cutelyst::ValidatorSize", "The value must be %1.").arg(size);
199  }
200  } else {
201  if (d->type == QMetaType::QString) {
202  //: %1 will be replaced by the field label, %2 will be replaced by the required string size
203  error = c->translate("Cutelyst::ValidatorSize", "The text in the “%1“ field must be exactly %2 characters long.").arg(_label, size);
204  } else {
205  //: %1 will be replaced by the field label, %2 will be replaced by the required size/value
206  error = c->translate("Cutelyst::ValidatorSize", "The value in the “%1” field must be %2.").arg(_label, size);
207  }
208  }
209 
210  return error;
211 }
212 
214 {
215  QString error;
216 
217  int field = errorData.toInt();
218  const QString _label = label(c);
219 
220  if (field == 0) {
221  Q_D(const ValidatorSize);
222  if (_label.isEmpty()) {
223  error = c->translate("Cutelyst::ValidatorSize", "The comparison type with ID %1 is not supported.").arg(static_cast<int>(d->type));
224  } else {
225  error = c->translate("Cutelyst::ValidatorSize", "The comparison type with ID %1 for the “%2” field is not supported.").arg(QString::number(static_cast<int>(d->type)), _label);
226  }
227  } else if (field == 1) {
228  if (_label.isEmpty()) {
229  error = c->translate("Cutelyst::ValidatorSize", "The comparison value is not valid.");
230  } else {
231  //: %1 will be replaced by the field label
232  error = c->translate("Cutelyst::ValidatorSize", "The comparison value for the “%1” field is not valid.").arg(_label);
233  }
234  }
235 
236  return error;
237 }
238 
240 {
241  QString error;
242  Q_UNUSED(errorData)
243  Q_D(const ValidatorSize);
244 
245  const QString _label = label(c);
246  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
247  if (_label.isEmpty()) {
248  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value into a floating point number.");
249  } else {
250  //: %1 will be replaced by the field label
251  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value for the “%1” field into a floating point number.").arg(_label);
252  }
253  } else {
254  if (_label.isEmpty()) {
255  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value into an integer number.");
256  } else {
257  //: %1 will be replaced by the field label
258  error = c->translate("Cutelyst::ValidatorSize", "Failed to parse the input value for the “%1” field into an integer number.").arg(_label);
259  }
260  }
261 
262  return error;
263 }
The Cutelyst Context.
Definition: context.h:39
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 label(Context *c) const
Returns the human readable field label used for generic error messages.
QString field() const
Returns the name of the field to validate.
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occured while parsing input.
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 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.
The field under validation must have a size matching the given value.
Definition: validatorsize.h:43
~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
qlonglong toLongLong(const QString &s, bool *ok) const const
QString toString(qlonglong i) const const
int size() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool isEmpty() const const
int length() const const
QString number(int n, int base)
double toDouble(bool *ok) const const
qulonglong toULongLong(bool *ok, int base) const const
bool isValid() const const
void setValue(const T &value)
int toInt(bool *ok) const const
QMap< QString, QVariant > toMap() const const
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49