Move SSD box type cache guards to typed Kotlin

ober

013223cab4e035484225dbb2a7879a0b1598905c

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index d5d8f98..89d025e 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -5,7 +5,8 @@
     (typed-kotlin-file "com/sfb/ssdreview/BoxType.kt"
       (typed-library (com sfb ssdreview)
         (export make-BoxType BoxType? BoxType-id BoxType-name box-type-display
-                boxTypeDisplays boxTypeById boxTypeDisplayById)
+                boxTypeDisplays boxTypeById boxTypeDisplayById
+                cachedBoxTypesPresent cachedBoxTypesOrEmpty addNullableBoxType)
         (type Int32)
         (record BoxType
           ((id : String)
@@ -33,7 +34,18 @@
           (let ((box (boxTypeById items id)))
             (if (nullable-null? box)
               id
-              (box-type-display (nullable-get box)))))))
+              (box-type-display (nullable-get box)))))
+        (def (cachedBoxTypesPresent (items : (Nullable (MutableList BoxType)))) : Bool
+          (not (nullable-null? items)))
+        (def (cachedBoxTypesOrEmpty (items : (Nullable (MutableList BoxType)))) : (MutableList BoxType)
+          (if (nullable-null? items)
+              (mutable-list-empty BoxType)
+              (nullable-get items)))
+        (def (addNullableBoxType (items : (MutableList BoxType))
+                                 (box : (Nullable BoxType))) : Unit
+          (if (nullable-null? box)
+              (begin)
+              (mutable-list-add! items (nullable-get box))))))
 
     (typed-kotlin-file "com/sfb/ssdreview/BoxTypeResolve.kt"
       (typed-library (com sfb ssdreview)
@@ -6177,14 +6189,14 @@
        "import android.content.Context"
        ""
        "object BoxTypes {"
-       "    private var cache: List<BoxType>? = null"
+       "    private var cache: MutableList<BoxType>? = null"
        ""
        "    fun load(context: Context): List<BoxType> {"
-       "        cache?.let { return it }"
+       "        if (cachedBoxTypesPresent(cache)) return cachedBoxTypesOrEmpty(cache)"
        "        val items = mutableListOf<BoxType>()"
        "        context.assets.open(\"box_types.csv\").bufferedReader().useLines { lines ->"
        "            lines.drop(1).forEach { line ->"
-       "                parseBoxTypeCsvLine(line)?.let { items.add(it) }"
+       "                addNullableBoxType(items, parseBoxTypeCsvLine(line))"
        "            }"
        "        }"
        "        cache = items"