feat: enhance validation and serialization with fiscal code checks and JSON schema support

This commit is contained in:
gabdevele
2026-06-14 21:09:05 +02:00 Unverified
parent feef498d9a
commit 002f89bd73
10 changed files with 282 additions and 32 deletions
+60 -3
View File
@@ -1,9 +1,44 @@
#include "common/Validation.h"
#include <array>
#include <cctype>
#include <regex>
namespace visione::validation
{
namespace
{
char normalizeFiscalCodeChar(char ch)
{
return static_cast<char>(
std::toupper(static_cast<unsigned char>(ch)));
}
int fiscalCodeControlValueForOdd(char ch)
{
static constexpr std::array<int, 26> letterValues{
1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18,
20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23};
static constexpr std::array<int, 10> digitValues{1, 0, 5, 7, 9,
13, 15, 17, 19, 21};
if (std::isdigit(static_cast<unsigned char>(ch)))
{
return digitValues[static_cast<size_t>(ch - '0')];
}
return letterValues[static_cast<size_t>(ch - 'A')];
}
int fiscalCodeControlValueForEven(char ch)
{
if (std::isdigit(static_cast<unsigned char>(ch)))
{
return ch - '0';
}
return ch - 'A';
}
} // namespace
bool hasString(const Json::Value &body, const std::string &key)
{
return body.isMember(key) && body[key].isString() &&
@@ -38,8 +73,30 @@ bool isValidEmail(const std::string &email)
bool isValidFiscalCode(const std::string &fiscalCode)
{
static const std::regex pattern(R"(^[A-Za-z0-9]{16}$)");
return std::regex_match(fiscalCode, pattern);
static const std::regex pattern(
R"(^[A-Za-z]{6}[0-9]{2}[ABCDEHLMPRST]{1}[0-9]{2}[A-Za-z][0-9]{3}[A-Za-z]$)");
if (!std::regex_match(fiscalCode, pattern))
{
return false;
}
std::string normalized;
normalized.reserve(fiscalCode.size());
for (char ch : fiscalCode)
{
normalized.push_back(normalizeFiscalCodeChar(ch));
}
int sum = 0;
for (size_t i = 0; i < normalized.size() - 1; ++i)
{
sum += ((i + 1) % 2 == 0) ? fiscalCodeControlValueForEven(normalized[i])
: fiscalCodeControlValueForOdd(normalized[i]);
}
const char expectedControl =
static_cast<char>('A' + (sum % 26));
return normalized.back() == expectedControl;
}
} // namespace visione::validation