Fri, 01 Nov 2024 17:35:42 +0100
treat integers and doubles both as JSON numbers
relates to #431
src/cx/json.h | file | annotate | diff | comparison | revisions | |
tests/test_json.c | file | annotate | diff | comparison | revisions |
--- a/src/cx/json.h Fri Nov 01 17:24:51 2024 +0100 +++ b/src/cx/json.h Fri Nov 01 17:35:42 2024 +0100 @@ -64,7 +64,7 @@ CX_JSON_OBJECT, CX_JSON_ARRAY, CX_JSON_STRING, - CX_JSON_INTEGER, // TODO: the spec does not know integer types + CX_JSON_INTEGER, CX_JSON_NUMBER, CX_JSON_LITERAL }; @@ -207,8 +207,7 @@ __attribute__((__nonnull__)) static inline bool cxJsonIsNumber(CxJsonValue *value) { - // TODO: this is not good, because an integer is also a number - return value->type == CX_JSON_NUMBER; + return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; } __attribute__((__nonnull__)) @@ -241,20 +240,37 @@ return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; } +__attribute__((__nonnull__, __returns_nonnull__)) +static inline char *cxJsonAsString(CxJsonValue *value) { + return value->value.string.ptr; +} + __attribute__((__nonnull__)) -static inline cxmutstr cxJsonAsString(CxJsonValue *value) { - // TODO: do we need a separate method to return this directly as cxstring? +static inline cxstring cxJsonAsCxString(CxJsonValue *value) { + return cx_strcast(value->value.string); +} + +__attribute__((__nonnull__)) +static inline cxmutstr cxJsonAsCxMutStr(CxJsonValue *value) { return value->value.string; } __attribute__((__nonnull__)) static inline double cxJsonAsDouble(CxJsonValue *value) { - return value->value.number; + if (value->type == CX_JSON_INTEGER) { + return (double) value->value.integer; + } else { + return value->value.number; + } } __attribute__((__nonnull__)) static inline int64_t cxJsonAsInteger(CxJsonValue *value) { - return value->value.integer; + if (value->type == CX_JSON_INTEGER) { + return value->value.integer; + } else { + return (int64_t) value->value.number; + } } __attribute__((__nonnull__))
--- a/tests/test_json.c Fri Nov 01 17:24:51 2024 +0100 +++ b/tests/test_json.c Fri Nov 01 17:35:42 2024 +0100 @@ -72,7 +72,7 @@ CxJsonValue *message = cxJsonObjGet(obj, "message"); CX_TEST_ASSERT(cxJsonIsString(message)); CX_TEST_ASSERT(0 == cx_strcmp( - cx_strcast(cxJsonAsString(message)), + cxJsonAsCxString(message), cx_str("success")) ); @@ -80,14 +80,20 @@ CX_TEST_ASSERT(cxJsonIsObject(position)); CxJsonValue *longitude = cxJsonObjGet(position, "longitude"); CX_TEST_ASSERT(cxJsonIsNumber(longitude)); + CX_TEST_ASSERT(!cxJsonIsInteger(longitude)); CX_TEST_ASSERT(cxJsonAsDouble(longitude) == -94.7099); + CX_TEST_ASSERT(cxJsonAsInteger(longitude) == -94); CxJsonValue *latitude = cxJsonObjGet(position, "latitude"); CX_TEST_ASSERT(cxJsonIsNumber(latitude)); + CX_TEST_ASSERT(!cxJsonIsInteger(latitude)); CX_TEST_ASSERT(cxJsonAsDouble(latitude) == 51.5539); + CX_TEST_ASSERT(cxJsonAsInteger(latitude) == 51); CxJsonValue *timestamp = cxJsonObjGet(obj, "timestamp"); CX_TEST_ASSERT(cxJsonIsInteger(timestamp)); + CX_TEST_ASSERT(cxJsonIsNumber(timestamp)); CX_TEST_ASSERT(cxJsonAsInteger(timestamp) == 1729348561); + CX_TEST_ASSERT(cxJsonAsDouble(timestamp) == 1729348561.0); CxJsonValue *alive = cxJsonObjGet(obj, "alive"); CX_TEST_ASSERT(cxJsonIsBool(alive)); @@ -140,7 +146,7 @@ CxJsonValue *message = cxJsonObjGet(obj, "message"); CX_TEST_ASSERT(cxJsonIsString(message)); CX_TEST_ASSERT(0 == cx_strcmp( - cx_strcast(cxJsonAsString(message)), + cxJsonAsCxString(message), cx_str("success")) ); CxJsonValue *timestamp = cxJsonObjGet(obj, "__timestamp");