default values for c++ class from json schema
Below is my json schema
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$ref": "#/definitions/ZeroToOneEnum",
"definitions": {
"ZeroToOneEnum": {
"additionalProperties": true,
"type": "string",
"format": "integer",
"default":0,
"enum": [
"0",
"1",
"Not Set"
]
}
}
}
even though i given default value quick type didn't generated a default value
// To parse this JSON data, first install
//
// Boost http://www.boost.org
// json.hpp https://github.com/nlohmann/json
//
// Then include this file, and then do
//
// ZeroToOneEnum data = nlohmann::json::parse(jsonString);
#pragma once
#include <nlohmann/json.hpp>
#include <boost/optional.hpp>
#include <stdexcept>
#include <regex>
namespace C3EThirdParty {
using nlohmann::json;
inline json get_untyped(const json & j, const char * property) {
if (j.find(property) != j.end()) {
return j.at(property).get<json>();
}
return json();
}
inline json get_untyped(const json & j, std::string property) {
return get_untyped(j, property.data());
}
enum class ZeroToOneEnum : int { NOT_SET, THE_0, THE_1 };
}
namespace nlohmann {
void from_json(const json & j, C3EThirdParty::ZeroToOneEnum & x);
void to_json(json & j, const C3EThirdParty::ZeroToOneEnum & x);
inline void from_json(const json & j, C3EThirdParty::ZeroToOneEnum & x) {
if (j == "Not Set") x = C3EThirdParty::ZeroToOneEnum::NOT_SET;
else if (j == "0") x = C3EThirdParty::ZeroToOneEnum::THE_0;
else if (j == "1") x = C3EThirdParty::ZeroToOneEnum::THE_1;
else throw "Input JSON does not conform to schema";
}
inline void to_json(json & j, const C3EThirdParty::ZeroToOneEnum & x) {
switch (x) {
case C3EThirdParty::ZeroToOneEnum::NOT_SET: j = "Not Set"; break;
case C3EThirdParty::ZeroToOneEnum::THE_0: j = "0"; break;
case C3EThirdParty::ZeroToOneEnum::THE_1: j = "1"; break;
default: throw "This should not happen";
}
}
}
what i am lookig for is if the ablove enum class added as member variable in other class, default constructor of this enum class should return a default value. with the above c++ class garabage value returned , when to_json is called it throwing an exception
default: throw "This should not happen"; is causing an exception. if input is other than in list. even though defualt value is provided to_json didn't generated it
This issue makes a problem with required scalar fields (Number or Integer) that have no default constructor. C++ degenerated code is then incorrect. Example:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "An object",
"type": "object",
"properties": {
"id": {
"type": "integer",
"default": 0
}
},
"required": [
"id"
],
"additionalProperties": false
}
output:
/**
* An object
*/
class Object {
public:
Object() = default;
virtual ~Object() = default;
private:
int64_t id;
public:
const int64_t & getId() const { return id; }
int64_t & getMutableId() { return id; }
void setId(const int64_t & value) { this->id = value; }
};
Default constructor will not set a default value for id, which is an error.
Expected output:
/**
* An object
*/
class Object {
public:
Object() = default;
virtual ~Object() = default;
private:
int64_t id = 0;
public:
const int64_t & getId() const { return id; }
int64_t & getMutableId() { return id; }
void setId(const int64_t & value) { this->id = value; }
};
Here's a patch for generating C++ default values that mostly works: https://gist.github.com/vnd/8e8b64268dca2bfe0f99a445bb0a7135
The only issue so far is with enums, which require trivial post-processing.