cutelyst  5.0.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatormax.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2025 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatormax_p.h"
7 
8 #include <QMetaType>
9 
10 using namespace Cutelyst;
11 
13  QMetaType::Type type,
14  const QVariant &max,
15  const Cutelyst::ValidatorMessages &messages,
16  const QString &defValKey)
17  : ValidatorRule(*new ValidatorMaxPrivate(field, type, max, messages, defValKey))
18 {
19 }
20 
21 ValidatorMax::~ValidatorMax() = default;
22 
24 {
25  ValidatorReturnType result;
26 
27  const QString v = value(params);
28 
29  if (!v.isEmpty()) {
30  Q_D(const ValidatorMax);
31  bool ok = false;
32  bool valid = false;
33 
34  switch (d->type) {
35  case QMetaType::Char:
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).noquote().nospace()
45  << debugString(c) << " Failed to parse \"" << v << "\" into an integer number";
46  } else {
47  const qlonglong max = ValidatorMaxPrivate::extractLongLong(c, params, d->max, &ok);
48  if (Q_UNLIKELY(!ok)) {
50  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
51  qCWarning(C_VALIDATOR).noquote()
52  << debugString(c) << "Invalid maximum comparison value";
53  } else {
54  if (val > max) {
55  result.errorMessage = validationError(c, max);
56  qCDebug(C_VALIDATOR).noquote()
57  << debugString(c) << val << "is not smaller than" << max;
58  } else {
59  valid = true;
60  }
61  }
62  }
63  } break;
64  case QMetaType::UChar:
65  case QMetaType::UShort:
66  case QMetaType::UInt:
67  case QMetaType::ULong:
69  {
70  const qulonglong val = v.toULongLong(&ok);
71  if (Q_UNLIKELY(!ok)) {
72  result.errorMessage = parsingError(c);
73  qCWarning(C_VALIDATOR).noquote().nospace()
74  << debugString(c) << " Failed to parse \"" << v
75  << "\" into an unsigned integer number";
76  } else {
77  const qulonglong max =
78  ValidatorMaxPrivate::extractULongLong(c, params, d->max, &ok);
79  if (Q_UNLIKELY(!ok)) {
81  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
82  qCWarning(C_VALIDATOR).noquote()
83  << debugString(c) << "Invalid maximum comparison value";
84  } else {
85  if (val > max) {
86  result.errorMessage = validationError(c, max);
87  qCDebug(C_VALIDATOR).noquote()
88  << debugString(c) << val << "is not smaller than" << max;
89  } else {
90  valid = true;
91  }
92  }
93  }
94  } break;
95  case QMetaType::Float:
96  case QMetaType::Double:
97  {
98  const double val = v.toDouble(&ok);
99  if (Q_UNLIKELY(!ok)) {
100  result.errorMessage = parsingError(c);
101  qCWarning(C_VALIDATOR).noquote().nospace()
102  << debugString(c) << " Failed to parse \"" << v
103  << "\" into a floating point number";
104  } else {
105  const double max = ValidatorMaxPrivate::extractDouble(c, params, d->max, &ok);
106  if (Q_UNLIKELY(!ok)) {
108  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
109  qCWarning(C_VALIDATOR).noquote()
110  << debugString(c) << "Invalid maximum comparison value";
111  } else {
112  if (val > max) {
113  result.errorMessage = validationError(c, max);
114  qCDebug(C_VALIDATOR).noquote()
115  << debugString(c) << val << "is not smaller than" << max;
116  } else {
117  valid = true;
118  }
119  }
120  }
121  } break;
122  case QMetaType::QString:
123  {
124  const auto val = static_cast<qlonglong>(v.length());
125  const qlonglong max = ValidatorMaxPrivate::extractLongLong(c, params, d->max, &ok);
126  if (Q_UNLIKELY(!ok)) {
128  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
129  qCWarning(C_VALIDATOR).noquote()
130  << debugString(c) << "Invalid maximum comparison value";
131  } else {
132  if (val > max) {
133  result.errorMessage = validationError(c, max);
134  qCDebug(C_VALIDATOR).noquote()
135  << debugString(c) << "String length" << val << "is not shorter than" << max;
136  } else {
137  valid = true;
138  }
139  }
140  } break;
141  default:
142  qCWarning(C_VALIDATOR).noquote()
143  << debugString(c) << "The comparison type" << d->type << "is not supported";
145  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidType));
146  break;
147  }
148 
149  if (valid) {
150  if (d->type != QMetaType::QString) {
151  const QVariant _v = ValidatorMaxPrivate::valueToNumber(c, v, d->type);
152  if (_v.isValid()) {
153  result.value = _v;
154  } else {
155  result.errorMessage = parsingError(c);
156  }
157  } else {
158  result.value.setValue(v);
159  }
160  }
161  } else {
162  defaultValue(c, &result);
163  }
164 
165  return result;
166 }
167 
169 {
170  cb(validate(c, params));
171 }
172 
174 {
175  Q_D(const ValidatorMax);
176 
177  QString max;
178  switch (d->type) {
179  case QMetaType::Char:
180  case QMetaType::Short:
181  case QMetaType::Int:
182  case QMetaType::Long:
183  case QMetaType::LongLong:
184  case QMetaType::QString:
185  max = c->locale().toString(errorData.toLongLong());
186  break;
187  case QMetaType::UChar:
188  case QMetaType::UShort:
189  case QMetaType::UInt:
190  case QMetaType::ULong:
192  max = c->locale().toString(errorData.toULongLong());
193  break;
194  case QMetaType::Float:
195  case QMetaType::Double:
196  max = c->locale().toString(errorData.toDouble());
197  break;
198  default:
199  return validationDataError(c,
200  static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidType));
201  }
202 
203  const QString _label = label(c);
204 
205  if (_label.isEmpty()) {
206  if (d->type == QMetaType::QString) {
207  //% "The text must be shorter than %1 characters."
208  return c->qtTrId("cutelyst-valmax-genvalerr-str").arg(max);
209  } else {
210  //% "The value must be lower than %1."
211  return c->qtTrId("cutelyst-valmax-genvalerr-num").arg(max);
212  }
213  } else {
214  if (d->type == QMetaType::QString) {
215  //% "The text in the “%1“ field must be shorter than %2 characters."
216  return c->qtTrId("cutelyst-valmax-genvalerr-str-label").arg(_label, max);
217  } else {
218  //% "The value in the “%1” field must be lower than %2."
219  return c->qtTrId("cutelyst-valmax-genvalerr-num-label").arg(_label, max);
220  }
221  }
222 }
223 
225 {
226  const QString _label = label(c);
227  const auto errorType = static_cast<ValidatorRulePrivate::ErrorType>(errorData.toInt());
228 
229  // translation strings are defined in ValidatorBetween
230 
231  if (_label.isEmpty()) {
232  switch (errorType) {
233  case ValidatorRulePrivate::ErrorType::InvalidType:
234  {
235  Q_D(const ValidatorMax);
236  const QMetaType _type(d->type);
237  return c->qtTrId("cutelyst-validator-genvaldataerr-type")
238  .arg(QString::fromLatin1(_type.name()));
239  }
240  case ValidatorRulePrivate::ErrorType::InvalidMax:
241  return c->qtTrId("cutelyst-validator-genvaldataerr-max");
242  case ValidatorRulePrivate::ErrorType::InvalidMin:
243  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
244  Q_UNREACHABLE();
245  return {};
246  }
247  } else {
248  switch (errorType) {
249  case ValidatorRulePrivate::ErrorType::InvalidType:
250  {
251  Q_D(const ValidatorMax);
252  const QMetaType _type(d->type);
253  return c->qtTrId("cutelyst-validator-genvaldataerr-type-label")
254  .arg(QString::fromLatin1(_type.name()), _label);
255  }
256  case ValidatorRulePrivate::ErrorType::InvalidMax:
257  return c->qtTrId("cutelyst-validator-genvaldataerr-max-label").arg(_label);
258  case ValidatorRulePrivate::ErrorType::InvalidMin:
259  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
260  Q_UNREACHABLE();
261  return {};
262  }
263  }
264 
265 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
266  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
267  Q_UNREACHABLE_RETURN({});
268 #else
269  return {};
270 #endif
271 }
272 
274 {
275  Q_UNUSED(errorData)
276  Q_D(const ValidatorMax);
277 
278  // translation strings are defined in ValidatorBetween
279 
280  const QString _label = label(c);
281  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
282  if (_label.isEmpty()) {
283  return c->qtTrId("cutelyst-validator-genparseerr-float");
284  } else {
285  return c->qtTrId("cutelyst-validator-genparseerr-float-label").arg(_label);
286  }
287  } else {
288  if (_label.isEmpty()) {
289  return c->qtTrId("cutelyst-validator-genparseerr-int");
290  } else {
291  return c->qtTrId("cutelyst-validator-genparseerr-int-label").arg(_label);
292  }
293  }
294 }
qlonglong toLongLong(bool *ok) const const
qlonglong toLongLong(QStringView s, bool *ok) const const
Stores custom error messages and the input field label.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
double toDouble(bool *ok) const const
qulonglong toULongLong(bool *ok) const const
QString toString(QDate date, FormatType format) const const
The Cutelyst Context.
Definition: context.h:42
void defaultValue(Context *c, ValidatorReturnType *result) const
int toInt(bool *ok) const const
QString genericParsingError(Context *c, const QVariant &errorData) const override
ValidatorMax(const QString &field, QMetaType::Type type, const QVariant &max, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey={})
bool isEmpty() const const
QString parsingError(Context *c, const QVariant &errorData={}) const
The Cutelyst namespace holds all public Cutelyst API.
QString debugString(const Context *c) const
Base class for all validator rules.
qulonglong toULongLong(bool *ok, int base) const const
QLocale locale() const noexcept
Definition: context.cpp:461
QString value(const ParamsMultiMap &params) const
QString label(const Context *c) const
std::function< void(ValidatorReturnType &&result)> ValidatorRtFn
Void callback function for validator rules that processes the ValidatorReturnType.
Definition: validatorrule.h:82
QString fromLatin1(QByteArrayView str)
const char * name() const const
QString validationError(Context *c, const QVariant &errorData={}) const
QString validationDataError(Context *c, const QVariant &errorData={}) const
QString qtTrId(const char *id, int n=-1) const
Definition: context.h:658
void validateCb(Context *c, const ParamsMultiMap &params, ValidatorRtFn cb) const override
qsizetype length() const const
bool isValid() const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Checks if a value is not bigger or longer than a maximum value.
Definition: validatormax.h:46
Contains the result of a single input parameter validation.
Definition: validatorrule.h:52
double toDouble(bool *ok) const const
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
QString arg(Args &&... args) const const
void setValue(QVariant &&value)