From 3da65370e0264df892ef6d1e2cb9e10d785b7683 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sat, 12 Sep 2026 19:55:17 -0500 Subject: [PATCH] Add requireStrMin save-JSON shorthand Replaces the hand-rolled mapName missing/null/empty check in saveSlotVer1ReadJSON with a reusable macro. Co-Authored-By: Claude Sonnet 5 --- src/dusk/save/savejson.h | 20 ++++++++++++++++++++ src/dusk/save/slot/saveslotver1.c | 13 +------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/dusk/save/savejson.h b/src/dusk/save/savejson.h index 7095b6c9..9537257e 100644 --- a/src/dusk/save/savejson.h +++ b/src/dusk/save/savejson.h @@ -481,6 +481,26 @@ #define requireString(key) \ if(!hasString(key)) errorThrow("Save JSON missing '%s' key", key) +/** + * Errors if the given key is missing, not a string, or a string shorter + * than the given minimum length - e.g. requireStrMin(key, 1) to reject a + * missing/null/empty string outright. + * + * @param key The key to check. + * @param len The minimum string length required. + */ +#define requireStrMin(key, len) { \ + yyjson_val *saveJsonStrMinVal = yyjson_obj_get(object, key); \ + if( \ + saveJsonStrMinVal == NULL || !yyjson_is_str(saveJsonStrMinVal) || \ + yyjson_get_len(saveJsonStrMinVal) < (size_t)(len) \ + ) { \ + errorThrow( \ + "Save JSON '%s' must be a string of at least length %d", key, (int)(len) \ + ); \ + } \ +} + /** * Writes a string to the current JSON object. The string is copied, so it * does not need to outlive the JSON document. diff --git a/src/dusk/save/slot/saveslotver1.c b/src/dusk/save/slot/saveslotver1.c index 834aaf3b..efb5cd9f 100644 --- a/src/dusk/save/slot/saveslotver1.c +++ b/src/dusk/save/slot/saveslotver1.c @@ -62,18 +62,7 @@ errorret_t saveSlotVer1ReadJSON(saveslotver1_t *slot, yyjson_val *object) { readTime("time", slot->time); readInt32("playerLevel", slot->playerLevel, 1); - - // A blank/never-used slot returned early above (see saveSlotInUse - - // keyed off "name"), so name is guaranteed non-empty here - and an - // in-use slot always has a map name too (see saveSlotNewGame). Missing, - // null, or empty means this save is corrupt. - yyjson_val *mapNameVal = yyjson_obj_get(object, "mapName"); - if( - mapNameVal == NULL || !yyjson_is_str(mapNameVal) || - yyjson_get_len(mapNameVal) == 0 - ) { - errorThrow("Save JSON 'mapName' must be a non-empty string"); - } + requireStrMin("mapName", 1); readString( "mapName", slot->mapName, "", SAVE_SLOT_VER1_MAP_NAME_MAX - 1 );