Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
xurxoham opened this issue Feb 1, 2019 · 3 comments
Closed

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

xurxoham opened this issue Feb 1, 2019 · 3 comments

Comments

@xurxoham
Copy link

xurxoham commented Feb 1, 2019

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.

@wing328
Copy link
Member

wing328 commented Feb 27, 2019

@xurxoham thanks for the suggestion. Given that you've already made the extensions, what about submitting a PR to start with so that we can review the enhancement more easily?

@xurxoham
Copy link
Author

xurxoham commented Mar 5, 2019

Sure. I'll try to make the PR once I get some spare time to isolate this from other things I added later on.

@etherealjoy
Copy link
Contributor

solved with #3417.
Pass useStructModel as true when invoking the generator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants