Search code examples
c++jsonserializationstructnlohmann-json

Problems serializing struct with nlohmann's json library


I am trying to serialize this struct with nlohmann's json library (the struct is defined in the file JsonResponsePacketSerializer.h):

typedef struct GetRoomsResponse
{
    unsigned int status;
    std::vector<RoomData> rooms;
}GetRoomsResponse;

where RoomData is another struct defined in the file Room.h:

typedef struct RoomData
{
    unsigned int id;
    std::string name;
    unsigned int maxPlayers;
    unsigned int numOfQuestionsInGame;
    unsigned int timePerQuestion;
    unsigned int isActive;
}RoomData;

To serialize this struct, I defined this user-macro as per nlohmann's documentation:

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GetRoomsResponse, status, rooms);

But this results in many errors I'm assuming because it doesn't know how to serialize the struct RoomData that is inside the struct GetRoomsResponse.

I tried adding a default constructor to RoomData (even though I'm pretty sure structs have a default constructor by default) and it didn't work.


Solution

  • As mentioned in the comments by @AlanBirties, all components of a struct must be serializable for the struct itself to be serializable (documentaiton).

    Here is some sample code which also declares the structures in the standard C++ style.

    Sample Code

    #include <iostream>
    #include "nlohmann/json.hpp"
    
    struct RoomData {
        unsigned int id;
        std::string name;
        unsigned int maxPlayers;
        unsigned int numOfQuestionsInGame;
        unsigned int timePerQuestion;
        unsigned int isActive;
    };
    
    struct GetRoomsResponse {
        unsigned int status;
        std::vector<RoomData> rooms;
    };
    
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(RoomData, id, name, maxPlayers, numOfQuestionsInGame, timePerQue\
    stion, isActive);
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GetRoomsResponse, status, rooms);
    
    int main(int argc, const char *argv[]) {
    
        RoomData r0{1, "abc", 2, 3, 4, 5}, r1{6, "def", 7, 8, 9, 10};
        GetRoomsResponse resp{0, {r0, r1}};
    
        nlohmann::json j{resp};
        cout << j << endl;
        return 0;
    }
    

    Output

    [{"rooms":[{"id":1,"isActive":5,"maxPlayers":2,"name":"abc","numOfQuestionsInGame":3,"timePerQue\
    stion":4},{"id":6,"isActive":10,"maxPlayers":7,"name":"def","numOfQuestionsInGame":8,"timePerQue\
    stion":9}],"status":0}]