cutelyst  5.0.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-2025 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 
22 {
23  ValidatorReturnType result;
24 
25  const QString v = value(params);
26 
27  if (!v.isEmpty()) {
28 
29  Q_D(const ValidatorSize);
30  bool ok = false;
31  bool valid = false;
32 
33  switch (d->type) {
34  case QMetaType::Short:
35  case QMetaType::Int:
36  case QMetaType::Long:
38  {
39  const auto val = c->locale().toLongLong(v, &ok);
40  if (Q_UNLIKELY(!ok)) {
41  result.errorMessage = parsingError(c);
42  qCWarning(C_VALIDATOR).noquote().nospace()
43  << debugString(c) << "Failed to parse \"" << v << "\" into an integer number";
44  } else {
45  const qlonglong size =
46  ValidatorSizePrivate::extractLongLong(c, params, d->size, &ok);
47  if (Q_UNLIKELY(!ok)) {
48  result.errorMessage = validationDataError(c, 1);
49  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
50  } else {
51  if (val != size) {
52  result.errorMessage = validationError(c, size);
53  qCDebug(C_VALIDATOR).noquote() << debugString(c) << val << "!=" << size;
54  } else {
55  valid = true;
56  }
57  }
58  }
59  } break;
60  case QMetaType::UShort:
61  case QMetaType::UInt:
62  case QMetaType::ULong:
64  {
65  const auto val = v.toULongLong(&ok);
66  if (Q_UNLIKELY(!ok)) {
67  result.errorMessage = parsingError(c);
68  qCWarning(C_VALIDATOR).noquote().nospace()
69  << debugString(c) << "Failed to parse \"" << v
70  << "\" into an unsigned integer number";
71  } else {
72  const qulonglong size =
73  ValidatorSizePrivate::extractULongLong(c, params, d->size, &ok);
74  if (Q_UNLIKELY(!ok)) {
75  result.errorMessage = validationDataError(c, 1);
76  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
77  } else {
78  if (val != size) {
79  result.errorMessage = validationError(c, size);
80  qCDebug(C_VALIDATOR).noquote() << debugString(c) << val << "!=" << size;
81  } else {
82  valid = true;
83  }
84  }
85  }
86  } break;
87  case QMetaType::Float:
88  case QMetaType::Double:
89  {
90  const auto val = v.toDouble(&ok);
91  if (Q_UNLIKELY(!ok)) {
92  result.errorMessage = parsingError(c);
93  qCWarning(C_VALIDATOR).noquote().nospace()
94  << debugString(c) << "Failed to parse \"" << v
95  << "\" into a floating point number";
96  } else {
97  const double size = ValidatorSizePrivate::extractDouble(c, params, d->size, &ok);
98  if (Q_UNLIKELY(!ok)) {
99  result.errorMessage = validationDataError(c, 1);
100  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
101  } else {
102  if (val != size) {
103  result.errorMessage = validationError(c, size);
104  qCDebug(C_VALIDATOR).noquote() << debugString(c) << val << "!=" << size;
105  } else {
106  valid = true;
107  }
108  }
109  }
110  } break;
111  case QMetaType::QString:
112  {
113  const auto val = static_cast<qlonglong>(v.length());
114  const qlonglong size = ValidatorSizePrivate::extractLongLong(c, params, d->size, &ok);
115  if (Q_UNLIKELY(!ok)) {
116  result.errorMessage = validationDataError(c, 1);
117  qCWarning(C_VALIDATOR).noquote() << debugString(c) << "Invalid comparison size";
118  } else {
119  if (val != size) {
120  result.errorMessage = validationError(c, size);
121  qCDebug(C_VALIDATOR).noquote()
122  << debugString(c) << "string length" << val << "!=" << size;
123  } else {
124  valid = true;
125  }
126  }
127  } break;
128  default:
129  qCWarning(C_VALIDATOR).noquote()
130  << debugString(c) << "The comparison type" << d->type << "is not supported";
131  result.errorMessage = validationDataError(c, 0);
132  break;
133  }
134 
135  if (valid) {
136  if (d->type != QMetaType::QString) {
137  const QVariant _v = ValidatorSizePrivate::valueToNumber(c, v, d->type);
138  if (_v.isValid()) {
139  result.value = _v;
140  } else {
141  result.errorMessage = parsingError(c);
142  }
143  } else {
144  result.value.setValue(v);
145  }
146  }
147  } else {
148  defaultValue(c, &result);
149  }
150 
151  return result;
152 }
153 
155 {
156  cb(validate(c, params));
157 }
158 
160 {
161  Q_D(const ValidatorSize);
162 
163  QString size;
164  switch (d->type) {
165  case QMetaType::Short:
166  case QMetaType::Int:
167  case QMetaType::Long:
168  case QMetaType::LongLong:
169  case QMetaType::QString:
170  size = c->locale().toString(errorData.toLongLong());
171  break;
172  case QMetaType::UShort:
173  case QMetaType::UInt:
174  case QMetaType::ULong:
176  size = c->locale().toString(errorData.toULongLong());
177  break;
178  case QMetaType::Float:
179  case QMetaType::Double:
180  size = c->locale().toString(errorData.toDouble());
181  break;
182  default:
183  return validationDataError(c, 0);
184  }
185 
186  const QString _label = label(c);
187 
188  if (_label.isEmpty()) {
189  if (d->type == QMetaType::QString) {
190  //% "The text must be exactly %1 characters long."
191  return c->qtTrId("cutelyst-valsize-genvalerr-str").arg(size);
192  } else {
193  //% "The value must be %1."
194  return c->qtTrId("cutelyst-valsize-genvalerr-num").arg(size);
195  }
196  } else {
197  if (d->type == QMetaType::QString) {
198  //: %1 will be replaced by the field label, %2 will be replaced by the required string
199  //: size
200  //% "The text in the “%1“ field must be exactly %2 characters long."
201  return c->qtTrId("cutelyst-valsize-genvalerr-str-label").arg(_label, size);
202  } else {
203  //: %1 will be replaced by the field label, %2 will be replaced by the required
204  //: size/value
205  //% "The value in the “%1” field must be %2."
206  return c->qtTrId("cutelyst-valsize-genvalerr-num-label").arg(_label, size);
207  }
208  }
209 }
210 
212 {
213  int field = errorData.toInt();
214  const QString _label = label(c);
215 
216  if (field == 0) {
217  Q_D(const ValidatorSize);
218  const QMetaType _type(d->type);
219  if (_label.isEmpty()) {
220  return c->qtTrId("cutelyst-validator-genvaldataerr-type")
221  .arg(QString::fromLatin1(_type.name()));
222  } else {
223  return c->qtTrId("cutelyst-validator-genvaldataerr-type-label")
224  .arg(QString::fromLatin1(_type.name()), _label);
225  }
226  } else {
227  if (_label.isEmpty()) {
228  //% "The comparison value is not valid."
229  return c->qtTrId("cutelyst-valsize-genvaldataerr-size");
230  } else {
231  //: %1 will be replaced by the field label
232  //% "The comparison value for the “%1” field is not valid."
233  return c->qtTrId("cutelyst-valsize-genvaldataerr-size-label").arg(_label);
234  }
235  }
236 }
237 
239 {
240  Q_UNUSED(errorData)
241  Q_D(const ValidatorSize);
242 
243  // translation strings are defined in ValidatorBetween
244 
245  const QString _label = label(c);
246  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
247  if (_label.isEmpty()) {
248  return c->qtTrId("cutelyst-validator-genparseerr-float");
249  } else {
250  return c->qtTrId("cutelyst-validator-genparseerr-float-label").arg(_label);
251  }
252  } else {
253  if (_label.isEmpty()) {
254  return c->qtTrId("cutelyst-validator-genparseerr-int");
255  } else {
256  return c->qtTrId("cutelyst-validator-genparseerr-int-label").arg(_label);
257  }
258  }
259 }
qlonglong toLongLong(bool *ok) const const
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
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
qulonglong toULongLong(bool *ok) const const
QString toString(QDate date, FormatType format) const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
The field under validation must have a size matching the given value.
Definition: validatorsize.h:49
The Cutelyst Context.
Definition: context.h:42
void defaultValue(Context *c, ValidatorReturnType *result) const
int toInt(bool *ok) const const
void validateCb(Context *c, const ParamsMultiMap &params, ValidatorRtFn cb) const override
bool isEmpty() const const
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
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
ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey={})
QString field() const noexcept
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
qsizetype length() const const
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
QString genericParsingError(Context *c, const QVariant &errorData) const override
void setValue(QVariant &&value)