Skip to content

[REQ] [C++] Improved C++ model code generation #2040

@xurxoham

Description

@xurxoham

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions