(cJSON) Enum Conversion Will Default to First Enum When Invalid or null data is provided
I have run into an issue where the cJSON implementation of enums produces what to me is an unacceptable result.
Take for instance the following enum:
"subscription": {
"type": "string",
"enum": [
"state",
"config",
"heartbeat"
]
}
The current cJSON implementation produces this result:
enum Subscription {
SUBSCRIPTION_CONFIG,
SUBSCRIPTION_HEARTBEAT,
SUBSCRIPTION_STATE
};
enum Subscription cJSON_GetSubscriptionValue(const cJSON * j) {
enum Subscription x = 0;
if (NULL != j) {
if (!strcmp(cJSON_GetStringValue(j), "config")) x = SUBSCRIPTION_CONFIG;
else if (!strcmp(cJSON_GetStringValue(j), "heartbeat")) x = SUBSCRIPTION_HEARTBEAT;
else if (!strcmp(cJSON_GetStringValue(j), "state")) x = SUBSCRIPTION_STATE;
}
return x;
}
The problem is that 0 is SUBSCRIPTION_CONFIG. That means when the subscription is null or something undefined the value returned is always SUBSCRIPTION_CONFIG.
The easiest way to correct this would be to always set the first enum = 1 when declaring the enum.
enum Subscription {
SUBSCRIPTION_CONFIG = 1,
SUBSCRIPTION_HEARTBEAT,
SUBSCRIPTION_STATE
};
I have this implemented as a styling option in my fork, but I am unsure if this is the best approach. I don't fully understand the base enum definition in quicktype. It looks like there is a provision for assigning values baked in, but I could not figure out how to make that happen.
Here is the relevant emit block that appears to have provision for emitting the enum with a value. I added the first ? " = 1" : "" but like i said before I am unsure if this is a good approach.
this.emitBlock(
["enum ", enumName],
() => {
const combinedName = allUpperWordStyle(this.sourcelikeToString(enumName));
this.forEachEnumCase(enumType, "none", (name, jsonName) => {
if (enumValues !== undefined) {
const [enumValue] = getAccessorName(enumValues, jsonName);
if (enumValue !== undefined) {
this.emitLine(combinedName, "_", name, " = ", enumValue.toString(), ",");
} else {
this.emitLine(combinedName, "_", name, first ? " = 1" : "", ",");
}
} else {
this.emitLine(combinedName, "_", name, first ? " = 1" : "", ",");
}
first = false;
});
},
"",
true
);