cutelyst  4.4.0
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-2023 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 = d->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 = d->extractULongLong(c, params, d->max, &ok);
78  if (Q_UNLIKELY(!ok)) {
80  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
81  qCWarning(C_VALIDATOR).noquote()
82  << debugString(c) << "Invalid maximum comparison value";
83  } else {
84  if (val > max) {
85  result.errorMessage = validationError(c, max);
86  qCDebug(C_VALIDATOR).noquote()
87  << debugString(c) << val << "is not smaller than" << max;
88  } else {
89  valid = true;
90  }
91  }
92  }
93  } break;
94  case QMetaType::Float:
95  case QMetaType::Double:
96  {
97  const double val = v.toDouble(&ok);
98  if (Q_UNLIKELY(!ok)) {
99  result.errorMessage = parsingError(c);
100  qCWarning(C_VALIDATOR).noquote().nospace()
101  << debugString(c) << " Failed to parse \"" << v
102  << "\" into a floating point number";
103  } else {
104  const double max = d->extractDouble(c, params, d->max, &ok);
105  if (Q_UNLIKELY(!ok)) {
107  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
108  qCWarning(C_VALIDATOR).noquote()
109  << debugString(c) << "Invalid maximum comparison value";
110  } else {
111  if (val > max) {
112  result.errorMessage = validationError(c, max);
113  qCDebug(C_VALIDATOR).noquote()
114  << debugString(c) << val << "is not smaller than" << max;
115  } else {
116  valid = true;
117  }
118  }
119  }
120  } break;
121  case QMetaType::QString:
122  {
123  const auto val = static_cast<qlonglong>(v.length());
124  const qlonglong max = d->extractLongLong(c, params, d->max, &ok);
125  if (Q_UNLIKELY(!ok)) {
127  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMax));
128  qCWarning(C_VALIDATOR).noquote()
129  << debugString(c) << "Invalid maximum comparison value";
130  } else {
131  if (val > max) {
132  result.errorMessage = validationError(c, max);
133  qCDebug(C_VALIDATOR).noquote()
134  << debugString(c) << "String length" << val << "is not shorter than" << max;
135  } else {
136  valid = true;
137  }
138  }
139  } break;
140  default:
141  qCWarning(C_VALIDATOR).noquote()
142  << debugString(c) << "The comparison type" << d->type << "is not supported";
144  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidType));
145  break;
146  }
147 
148  if (valid) {
149  if (d->type != QMetaType::QString) {
150  const QVariant _v = d->valueToNumber(c, v, d->type);
151  if (_v.isValid()) {
152  result.value = _v;
153  } else {
154  result.errorMessage = parsingError(c);
155  }
156  } else {
157  result.value.setValue(v);
158  }
159  }
160  } else {
161  defaultValue(c, &result);
162  }
163 
164  return result;
165 }
166 
168 {
169  Q_D(const ValidatorMax);
170 
171  QString max;
172  switch (d->type) {
173  case QMetaType::Char:
174  case QMetaType::Short:
175  case QMetaType::Int:
176  case QMetaType::Long:
177  case QMetaType::LongLong:
178  case QMetaType::QString:
179  max = c->locale().toString(errorData.toLongLong());
180  break;
181  case QMetaType::UChar:
182  case QMetaType::UShort:
183  case QMetaType::UInt:
184  case QMetaType::ULong:
186  max = c->locale().toString(errorData.toULongLong());
187  break;
188  case QMetaType::Float:
189  case QMetaType::Double:
190  max = c->locale().toString(errorData.toDouble());
191  break;
192  default:
193  return validationDataError(c,
194  static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidType));
195  }
196 
197  const QString _label = label(c);
198 
199  if (_label.isEmpty()) {
200  if (d->type == QMetaType::QString) {
201  //% "The text must be shorter than %1 characters."
202  return c->qtTrId("cutelyst-valmax-genvalerr-str").arg(max);
203  } else {
204  //% "The value must be lower than %1."
205  return c->qtTrId("cutelyst-valmax-genvalerr-num").arg(max);
206  }
207  } else {
208  if (d->type == QMetaType::QString) {
209  //% "The text in the “%1“ field must be shorter than %2 characters."
210  return c->qtTrId("cutelyst-valmax-genvalerr-str-label").arg(_label, max);
211  } else {
212  //% "The value in the “%1” field must be lower than %2."
213  return c->qtTrId("cutelyst-valmax-genvalerr-num-label").arg(_label, max);
214  }
215  }
216 }
217 
219 {
220  const QString _label = label(c);
221  const auto errorType = static_cast<ValidatorRulePrivate::ErrorType>(errorData.toInt());
222 
223  // translation strings are defined in ValidatorBetween
224 
225  if (_label.isEmpty()) {
226  switch (errorType) {
227  case ValidatorRulePrivate::ErrorType::InvalidType:
228  {
229  Q_D(const ValidatorMax);
230  const QMetaType _type(d->type);
231  return c->qtTrId("cutelyst-validator-genvaldataerr-type")
232  .arg(QString::fromLatin1(_type.name()));
233  }
234  case ValidatorRulePrivate::ErrorType::InvalidMax:
235  return c->qtTrId("cutelyst-validator-genvaldataerr-max");
236  case ValidatorRulePrivate::ErrorType::InvalidMin:
237  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
238  Q_UNREACHABLE();
239  return {};
240  }
241  } else {
242  switch (errorType) {
243  case ValidatorRulePrivate::ErrorType::InvalidType:
244  {
245  Q_D(const ValidatorMax);
246  const QMetaType _type(d->type);
247  return c->qtTrId("cutelyst-validator-genvaldataerr-type-label")
248  .arg(QString::fromLatin1(_type.name()), _label);
249  }
250  case ValidatorRulePrivate::ErrorType::InvalidMax:
251  return c->qtTrId("cutelyst-validator-genvaldataerr-max-label").arg(_label);
252  case ValidatorRulePrivate::ErrorType::InvalidMin:
253  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
254  Q_UNREACHABLE();
255  return {};
256  }
257  }
258 
259 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
260  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
261  Q_UNREACHABLE_RETURN({});
262 #else
263  return {};
264 #endif
265 }
266 
268 {
269  Q_UNUSED(errorData)
270  Q_D(const ValidatorMax);
271 
272  // translation strings are defined in ValidatorBetween
273 
274  const QString _label = label(c);
275  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
276  if (_label.isEmpty()) {
277  return c->qtTrId("cutelyst-validator-genparseerr-float");
278  } else {
279  return c->qtTrId("cutelyst-validator-genparseerr-float-label").arg(_label);
280  }
281  } else {
282  if (_label.isEmpty()) {
283  return c->qtTrId("cutelyst-validator-genparseerr-int");
284  } else {
285  return c->qtTrId("cutelyst-validator-genparseerr-int-label").arg(_label);
286  }
287  }
288 }
The Cutelyst Context.
Definition: context.h:42
QLocale locale() const noexcept
Definition: context.cpp:460
QString qtTrId(const char *id, int n=-1) const
Definition: context.h:656
Checks if a value is not bigger or longer than a maximum value.
Definition: validatormax.h:47
ValidatorMax(const QString &field, QMetaType::Type type, const QVariant &max, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
QString genericParsingError(Context *c, const QVariant &errorData) const override
Base class for all validator rules.
QString validationError(Context *c, const QVariant &errorData={}) const
QString label(Context *c) const
QString validationDataError(Context *c, const QVariant &errorData={}) const
void defaultValue(Context *c, ValidatorReturnType *result) const
QString value(const ParamsMultiMap &params) const
QString parsingError(Context *c, const QVariant &errorData={}) const
QString debugString(Context *c) const
The Cutelyst namespace holds all public Cutelyst API.
qlonglong toLongLong(QStringView s, bool *ok) const const
QString toString(QDate date, QLocale::FormatType format) const const
const char * name() const const
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
qsizetype length() const const
double toDouble(bool *ok) const const
qulonglong toULongLong(bool *ok, int base) const const
bool isValid() const const
void setValue(QVariant &&value)
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
qlonglong toLongLong(bool *ok) const const
qulonglong toULongLong(bool *ok) const const
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49