[C++][Pistache] Fixes for struct model (#12006)

* [C++][Pistache] fix Wconversion warning

* [C++][Pistache] fix struct model compilation with std::optional

* [C++][Pistache] Add validation to struct model
This commit is contained in:
ppngn
2022-05-01 18:11:19 +02:00
committed by GitHub
parent e342513391
commit 153e1db8a1
4 changed files with 88 additions and 8 deletions

View File

@@ -37,15 +37,21 @@ namespace
bool validateRfc3339_date(const std::string& str) {
std::smatch match;
const bool found = std::regex_search(str, match, regexRfc3339_date);
return found && validateDateValues(std::stoi(match[1]), std::stoi(match[2]), std::stoi(match[3]));
return found && validateDateValues(static_cast<uint16_t>(std::stoi(match[1])),
static_cast<uint16_t>(std::stoi(match[2])),
static_cast<uint16_t>(std::stoi(match[3])));
}
bool validateRfc3339_date_time(const std::string& str) {
std::smatch match;
const bool found = std::regex_search(str, match, regexRfc3339_date_time);
return found
&& validateDateValues(std::stoi(match[1]), std::stoi(match[2]), std::stoi(match[3]))
&& validateTimeValues(std::stoi(match[4]), std::stoi(match[5]), std::stoi(match[6]));
&& validateDateValues(static_cast<uint16_t>(std::stoi(match[1])),
static_cast<uint16_t>(std::stoi(match[2])),
static_cast<uint16_t>(std::stoi(match[3])))
&& validateTimeValues(static_cast<uint16_t>(std::stoi(match[4])),
static_cast<uint16_t>(std::stoi(match[5])),
static_cast<uint16_t>(std::stoi(match[6])));
}
std::string toStringValue(const std::string &value){

View File

@@ -26,6 +26,23 @@ struct {{classname}}
bool operator==(const {{classname}}& other) const;
bool operator!=(const {{classname}}& other) const;
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes an error
/// message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and calls it's validate.
/// Not meant to be called outside that case.
/// </summary>
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
nlohmann::json to_json() const;
static {{classname}} from_json(const nlohmann::json& j);
};

View File

@@ -2,6 +2,7 @@
{{#models}}{{#model}}
#include "{{classname}}.h"
#include "{{prefix}}Helpers.h"
namespace {{modelNamespace}}
{
@@ -20,6 +21,56 @@ nlohmann::json {{classname}}::to_json() const
return o;
}
void {{classname}}::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw {{helpersNamespace}}::ValidationException(msg.str());
}
}
bool {{classname}}::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool {{classname}}::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "{{classname}}" : pathPrefix;
{{#isEnum}}{{! Special case for enum types }}
if (m_value == {{classname}}::e{{classname}}::INVALID_VALUE_OPENAPI_GENERATED)
{
success = false;
msg << _pathPrefix << ": has no value;";
}
{{/isEnum}}
{{^isEnum}}
{{#vars}}
{{#isArray}} {{! Always generate validation body for array types }}
{{^required}}if ({{name}}.has_value()){{/required}}
{{#required}}/* {{name}} */ {{/required}}{
const {{{dataType}}}& value = {{name}}{{^required}}.value(){{/required}};
const std::string currentValuePath = _pathPrefix + ".{{nameInCamelCase}}";
{{> model-validation-body }}
}
{{/isArray}}{{^isArray}}{{#hasValidation}} {{! Only generate validation if necessary }}
{{^required}}if ({{name}}.has_value()){{/required}}
{{#required}}/* {{name}} */ {{/required}}{
const {{{dataType}}}& value = {{name}}{{^required}}.value(){{/required}};
const std::string currentValuePath = _pathPrefix + ".{{nameInCamelCase}}";
{{> model-validation-body }}
}
{{/hasValidation}}{{/isArray}}{{/vars}}{{/isEnum}}{{#vendorExtensions.x-is-string-enum-container}}{{#anyOf}}{{#-first}}
if (!m_value.validate(msg))
{
success = false;
}{{/-first}}{{/anyOf}}{{/vendorExtensions.x-is-string-enum-container}}
return success;
}
bool {{classname}}::operator==(const {{classname}}& other) const
{
return {{#vars}}{{name}} == other.{{name}}{{^-last}} && {{/-last}}{{/vars}};
@@ -33,8 +84,8 @@ bool {{classname}}::operator!=(const {{classname}}& other) const
void to_json(nlohmann::json& j, const {{classname}}& o)
{
{{#vars}}
{{^required}}if (!o.{{name}}.isEmpty()){{/required}}
j["{{baseName}}"] = o.{{name}}{{^required}}.get(){{/required}};
{{^required}}if (o.{{name}}.has_value()){{/required}}
j["{{baseName}}"] = o.{{name}}{{^required}}.value(){{/required}};
{{/vars}}
}

View File

@@ -47,15 +47,21 @@ namespace
bool validateRfc3339_date(const std::string& str) {
std::smatch match;
const bool found = std::regex_search(str, match, regexRfc3339_date);
return found && validateDateValues(std::stoi(match[1]), std::stoi(match[2]), std::stoi(match[3]));
return found && validateDateValues(static_cast<uint16_t>(std::stoi(match[1])),
static_cast<uint16_t>(std::stoi(match[2])),
static_cast<uint16_t>(std::stoi(match[3])));
}
bool validateRfc3339_date_time(const std::string& str) {
std::smatch match;
const bool found = std::regex_search(str, match, regexRfc3339_date_time);
return found
&& validateDateValues(std::stoi(match[1]), std::stoi(match[2]), std::stoi(match[3]))
&& validateTimeValues(std::stoi(match[4]), std::stoi(match[5]), std::stoi(match[6]));
&& validateDateValues(static_cast<uint16_t>(std::stoi(match[1])),
static_cast<uint16_t>(std::stoi(match[2])),
static_cast<uint16_t>(std::stoi(match[3])))
&& validateTimeValues(static_cast<uint16_t>(std::stoi(match[4])),
static_cast<uint16_t>(std::stoi(match[5])),
static_cast<uint16_t>(std::stoi(match[6])));
}
std::string toStringValue(const std::string &value){