-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
Is your feature request related to a problem? Please describe.
Model class generation for Pistache server C++ generator can be vastly improved. This changes, though, break with existing code but also get rid of unnecessary polymorphism and code complexity. Since this is a C++ language feature, other C++ code generators could leverage this improvement as well.
Describe the solution you'd like
Existing generated code relies on nlohmann::json library to serialize and deserialize bewteen JSON and real objects. This library provides the necessary mechanisms to perform those translations with free functions, leaving the model datatypes with a clean interface (no more fromJson and toJson).
Example:
error.yaml:
Error:
type: object
required: [ code, message ]
properties:
code:
type: integer
format : int32
message:
type: string
Generated code:
Error.hpp:
#include <cstdint>
#include <string>
#include <json.hpp>
namespace package {
/*!
* \class Error
*/
class Error
{
public:
//! Constructor for class Error
Error( int32_t code, std::string message );
//! Destructor for class Error
~Error() = default;
// Error member access functions
//! Returns Code's current value
int32_t getCode() const { return m_Code; }
//! Updates Code's current value
void setCode(int32_t value) { m_Code = value; }
//! Returns a reference to Message's current value
std::string& getMessage() { return m_Message; }
//! Returns read only reference to Message's current value
const std::string& getMessage() const { return m_Message; }
//! Updates Message's current value
void setMessage(std::string value) { m_Message = value; }
private:
int32_t m_Code;
std::string m_Message;
};
template<>
struct adl_serializer<Error> {
static Error from_json( const json& from );
static void to_json( json& to, const Error& from );
};
} // namespace package
Error.cpp:
#include "Error.hpp"
namespace package {
//! Constructor for class Error
Error::Error(int32_t code, std::string message) :
m_Code(std::move(code)),
m_Message(std::move(message))
{
}
Error
adl_serializer<Error>::from_json( const json& from )
{
int32_t code = from.at("code");
std::string message = from.at("message");
return Error( std::move(code), std::move(message) );
}
void
adl_serializer<Error>::to_json(
json& to,
const Error& from )
{
to = json::object();
to["code"] = from.getCode();
to["message"] = from.getMessage();
}
} // namespace package
Since nlohmann::json already provides proper overloads for basic datatypes such as std::string and int32_t, it is not necessary to worry about them, the nlohmann::basic_json::operator= will call the proper function.
This method handles composes really well. We can have other definitions containing errors without the necessity of re-implementing the serialization again (from this point on we handle an Error instance serialization/deserialization as we do here with std::string and int32_t, providing we include Error.hpp. It can also leverage enumerations (which if I remember correctly are not supported).
This method does not rely on RTTI, hence the runtime type information, virtual tables and the implicit vtable pointer are not necessary any more.
I made this extension myself to the previous swagger-codegen a year ago, but I'm keen to contribute with this improvement and enumeration support if it raises enough interest from the maintainers.