cutelyst  5.0.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatormin.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2025 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatormin_p.h"
7 
8 using namespace Cutelyst;
9 
11  QMetaType::Type type,
12  const QVariant &min,
13  const Cutelyst::ValidatorMessages &messages,
14  const QString &defValKey)
15  : ValidatorRule(*new ValidatorMinPrivate(field, type, min, messages, defValKey))
16 {
17 }
18 
19 ValidatorMin::~ValidatorMin() = default;
20 
22 {
23  ValidatorReturnType result;
24 
25  const QString v = value(params);
26 
27  Q_D(const ValidatorMin);
28 
29  if (!v.isEmpty()) {
30  bool ok = false;
31  bool valid = false;
32 
33  switch (d->type) {
34  case QMetaType::Char:
35  case QMetaType::Short:
36  case QMetaType::Int:
37  case QMetaType::Long:
39  {
40  const qlonglong val = c->locale().toLongLong(v, &ok);
41  if (Q_UNLIKELY(!ok)) {
42  result.errorMessage = parsingError(c);
43  qCWarning(C_VALIDATOR).noquote().nospace()
44  << debugString(c) << " Failed to parse \"" << v << "\" into an integer number";
45  } else {
46  const qlonglong min = ValidatorMinPrivate::extractLongLong(c, params, d->min, &ok);
47  if (Q_UNLIKELY(!ok)) {
49  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMin));
50  qCWarning(C_VALIDATOR).noquote()
51  << debugString(c) << "Invalid minimum comparison value";
52  } else {
53  if (val < min) {
54  result.errorMessage = validationError(c, min);
55  qCDebug(C_VALIDATOR).noquote()
56  << debugString(c) << val << "is not greater than" << min;
57  } else {
58  valid = true;
59  }
60  }
61  }
62  } break;
63  case QMetaType::UChar:
64  case QMetaType::UShort:
65  case QMetaType::UInt:
66  case QMetaType::ULong:
68  {
69  const qulonglong val = v.toULongLong(&ok);
70  if (Q_UNLIKELY(!ok)) {
71  result.errorMessage = parsingError(c);
72  qCWarning(C_VALIDATOR).noquote().nospace()
73  << debugString(c) << " Failed to parse \"" << v
74  << "\" into an unsigned integer number";
75  } else {
76  const qulonglong min =
77  ValidatorMinPrivate::extractULongLong(c, params, d->min, &ok);
78  if (Q_UNLIKELY(!ok)) {
80  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMin));
81  qCWarning(C_VALIDATOR).noquote()
82  << debugString(c) << "Invalid minimum comparison value";
83  } else {
84  if (val < min) {
85  result.errorMessage = validationError(c, min);
86  qCDebug(C_VALIDATOR).noquote()
87  << debugString(c) << val << "is not greater than" << min;
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 min = ValidatorMinPrivate::extractDouble(c, params, d->min, &ok);
105  if (Q_UNLIKELY(!ok)) {
107  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMin));
108  qCWarning(C_VALIDATOR).noquote()
109  << debugString(c) << "Invalid minimum comparison value";
110  } else {
111  if (val < min) {
112  result.errorMessage = validationError(c, min);
113  qCDebug(C_VALIDATOR).noquote()
114  << debugString(c) << val << "is not greater than" << min;
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 min = ValidatorMinPrivate::extractLongLong(c, params, d->min, &ok);
125  if (Q_UNLIKELY(!ok)) {
127  c, static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidMin));
128  qCWarning(C_VALIDATOR).noquote()
129  << debugString(c) << "Invalid minimum comparison value";
130  } else {
131  if (val < min) {
132  result.errorMessage = validationError(c, min);
133  qCDebug(C_VALIDATOR).noquote()
134  << debugString(c) << "String length" << val << "is not longer than" << min;
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 = ValidatorMinPrivate::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  cb(validate(c, params));
170 }
171 
173 {
174  Q_D(const ValidatorMin);
175 
176  QString min;
177  switch (d->type) {
178  case QMetaType::Char:
179  case QMetaType::Short:
180  case QMetaType::Int:
181  case QMetaType::Long:
182  case QMetaType::LongLong:
183  case QMetaType::QString:
184  min = c->locale().toString(errorData.toLongLong());
185  break;
186  case QMetaType::UChar:
187  case QMetaType::UShort:
188  case QMetaType::UInt:
189  case QMetaType::ULong:
191  min = c->locale().toString(errorData.toULongLong());
192  break;
193  case QMetaType::Float:
194  case QMetaType::Double:
195  min = c->locale().toString(errorData.toDouble());
196  break;
197  default:
198  return validationDataError(c,
199  static_cast<int>(ValidatorRulePrivate::ErrorType::InvalidType));
200  }
201 
202  const QString _label = label(c);
203 
204  if (_label.isEmpty()) {
205  if (d->type == QMetaType::QString) {
206  //% "The text must be longer than %1 characters."
207  return c->qtTrId("cutelyst-valmin-genvalerr-str").arg(min);
208  } else {
209  //% "The value must be greater than %1."
210  return c->qtTrId("cutelyst-valmin-genvalerr-num").arg(min);
211  }
212  } else {
213  if (d->type == QMetaType::QString) {
214  //% "The text in the “%1“ field must be longer than %2 characters."
215  return c->qtTrId("cutelyst-valmin-genvalerr-str-label").arg(_label, min);
216  } else {
217  //% "The value in the “%1” field must be greater than %2."
218  return c->qtTrId("cutelyst-valmin-genvalerr-num-label").arg(_label, min);
219  }
220  }
221 }
222 
224 {
225  const QString _label = label(c);
226  const auto errorType = static_cast<ValidatorRulePrivate::ErrorType>(errorData.toInt());
227 
228  // translation strings are defined in ValidatorBetween
229 
230  if (_label.isEmpty()) {
231  switch (errorType) {
232  case ValidatorRulePrivate::ErrorType::InvalidType:
233  {
234  Q_D(const ValidatorMin);
235  const QMetaType _type(d->type);
236  return c->qtTrId("cutelyst-validator-genvaldataerr-type")
237  .arg(QString::fromLatin1(_type.name()));
238  }
239  case ValidatorRulePrivate::ErrorType::InvalidMin:
240  return c->qtTrId("cutelyst-validator-genvaldataerr-min");
241  case ValidatorRulePrivate::ErrorType::InvalidMax:
242  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
243  Q_UNREACHABLE();
244  return {};
245  }
246  } else {
247  switch (errorType) {
248  case ValidatorRulePrivate::ErrorType::InvalidType:
249  {
250  Q_D(const ValidatorMin);
251  const QMetaType _type(d->type);
252  return c->qtTrId("cutelyst-validator-genvaldataerr-type-label")
253  .arg(QString::fromLatin1(_type.name()), _label);
254  }
255  case ValidatorRulePrivate::ErrorType::InvalidMin:
256  return c->qtTrId("cutelyst-validator-genvaldataerr-min-label").arg(_label);
257  case ValidatorRulePrivate::ErrorType::InvalidMax:
258  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
259  Q_UNREACHABLE();
260  return {};
261  }
262  }
263 
264 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
265  // NOLINTNEXTLINE(cppcoreguidelines-avoid-do-while)
266  Q_UNREACHABLE_RETURN({});
267 #else
268  return {};
269 #endif
270 }
271 
273 {
274  Q_UNUSED(errorData)
275  Q_D(const ValidatorMin);
276 
277  // translation strings are defined in ValidatorBetween
278 
279  const QString _label = label(c);
280  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
281  if (_label.isEmpty()) {
282  return c->qtTrId("cutelyst-validator-genparseerr-float");
283  } else {
284  return c->qtTrId("cutelyst-validator-genparseerr-float-label").arg(_label);
285  }
286  } else {
287  if (_label.isEmpty()) {
288  return c->qtTrId("cutelyst-validator-genparseerr-int");
289  } else {
290  return c->qtTrId("cutelyst-validator-genparseerr-int-label").arg(_label);
291  }
292  }
293 }
qlonglong toLongLong(bool *ok) const const
QString genericParsingError(Context *c, const QVariant &errorData) const override
qlonglong toLongLong(QStringView s, bool *ok) const const
Stores custom error messages and the input field label.
double toDouble(bool *ok) const const
qulonglong toULongLong(bool *ok) const const
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
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
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
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
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
Checks if a value is not smaller or shorter than a maximum value.
Definition: validatormin.h:46
qsizetype length() const const
void validateCb(Context *c, const ParamsMultiMap &params, ValidatorRtFn cb) const override
bool isValid() const const
Contains the result of a single input parameter validation.
Definition: validatorrule.h:52
double toDouble(bool *ok) const const
QString arg(Args &&... args) const const
ValidatorMin(const QString &field, QMetaType::Type type, const QVariant &min, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey={})
void setValue(QVariant &&value)