Move SSD box type display lookup to typed Kotlin

ober

ba4e115d65a808c6121ec10ddb6c57fc4589ff25

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 68687d7..e1478e5 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4,14 +4,36 @@
   '(
     (typed-kotlin-file "com/sfb/ssdreview/BoxType.kt"
       (typed-library (com sfb ssdreview)
-        (export make-BoxType BoxType? BoxType-id BoxType-name box-type-display)
+        (export make-BoxType BoxType? BoxType-id BoxType-name box-type-display
+                boxTypeDisplays boxTypeById boxTypeDisplayById)
+        (type Int32)
         (record BoxType
           ((id : String)
            (name : String)))
         (def (box-type-display (box : BoxType)) : String
           (string-append
             (string-append (BoxType-id box) " ")
-            (BoxType-name box)))))
+            (BoxType-name box)))
+        (def (boxTypeDisplays (items : (List BoxType))) : (MutableList String)
+          (for/fold ((out (mutable-list-empty String)))
+                    ((i (in-range (int32 0) (list-size items))))
+            (begin
+              (mutable-list-add! out (box-type-display (list-ref items i)))
+              out)))
+        (def (boxTypeById (items : (List BoxType)) (id : String)) : (Nullable BoxType)
+          (for/fold ((found (nullable-none BoxType)))
+                    ((i (in-range (int32 0) (list-size items))))
+            (if (nullable-null? found)
+              (let ((box (list-ref items i)))
+                (if (equal? (BoxType-id box) id)
+                  (nullable-some box)
+                  found))
+              found)))
+        (def (boxTypeDisplayById (items : (List BoxType)) (id : String)) : String
+          (let ((box (boxTypeById items id)))
+            (if (nullable-null? box)
+              id
+              (box-type-display (nullable-get box)))))))
 
     (typed-kotlin-file "com/sfb/ssdreview/BoxTypeResolve.kt"
       (typed-library (com sfb ssdreview)
@@ -3410,6 +3432,10 @@
        "        return resolveBoxType(load(context), raw)"
        "    }"
        ""
+       "    fun display(context: Context, id: String): String {"
+       "        return boxTypeDisplayById(load(context), id)"
+       "    }"
+       ""
        "}"
        ))
     (kotlin-file-lines "com/sfb/ssdreview/MainActivity.kt"
@@ -3479,7 +3505,7 @@
 	       "    private var ssdAreaMode: Boolean = false"
 	       "    private var reopenSsdBrowserOnResume: Boolean = false"
        "    @Volatile private var loadGeneration: Int = 0"
-       "    private val boxTypeDisplays: List<String> by lazy { BoxTypes.load(this).map { box_type_display(it) } }"
+       "    private val boxTypeDisplays: List<String> by lazy { boxTypeDisplays(BoxTypes.load(this)) }"
        "    private val firingArcDisplays = listOf("
        "        \"FA\","
        "        \"FH\","
@@ -3691,7 +3717,7 @@
        "    }"
        ""
        "    private fun finalizeGroupLabel(group: SsdGroup) {"
-       "        val typeDisplay = BoxTypes.load(this).firstOrNull { it.id == group.boxTypeId }?.let { box_type_display(it) } ?: group.boxTypeId"
+       "        val typeDisplay = BoxTypes.display(this, group.boxTypeId)"
        "        val resolved = resolvedLabelForBoxTypeAndroid(this, group.label, typeDisplay, group.boxTypeId)"
        "        if (resolved.isNotBlank()) {"
        "            group.label = resolved"
@@ -4367,15 +4393,13 @@
        "        val label = EditText(this).apply {"
        "            hint = \"Label\""
        "            inputType = InputType.TYPE_CLASS_TEXT"
-       "            val existing = BoxTypes.load(this@MainActivity).firstOrNull { it.id == group.boxTypeId }"
-       "            val typeDisplay = existing?.let { box_type_display(it) } ?: group.boxTypeId"
+       "            val typeDisplay = BoxTypes.display(this@MainActivity, group.boxTypeId)"
        "            setText(resolvedLabelForBoxTypeAndroid(this@MainActivity, group.label, typeDisplay, group.boxTypeId))"
        "            selectAll()"
        "        }"
        "        val boxType = boxTypeInput().apply {"
        "            hint = \"Box type id/name\""
-       "            val existing = BoxTypes.load(this@MainActivity).firstOrNull { it.id == group.boxTypeId }"
-       "            setText(existing?.let { box_type_display(it) } ?: group.boxTypeId, false)"
+       "            setText(BoxTypes.display(this@MainActivity, group.boxTypeId), false)"
        "        }"
        "        val firingArc = firingArcInput().apply {"
        "            setText(group.firingArc, false)"