Generate SSD box type CSV parsing from typed Jerboa

ober

ffb7d56241da9e7f38858c1e25c15b1835e1b5b8

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 09c7d81..233721d 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -163,7 +163,9 @@
 
     (typed-kotlin-file "com/sfb/ssdreview/BoxTypeCsv.kt"
       (typed-library (com sfb ssdreview)
-        (export parseBoxTypeCsvLine)
+        (export parseBoxTypeCsvLine boxTypesFromCsvText)
+        (extern (boxTypeCsvStringLines (text : String)) : (List String)
+          (kotlin-member-call lines))
         (def (parseBoxTypeCsvLine (line : String)) : (Nullable BoxType)
           (if (not (string-matches-regex? line "^[^,]+,.+$"))
               (nullable-none BoxType)
@@ -171,7 +173,16 @@
                     (name (string-trim (string-replace-regex line "^[^,]*," ""))))
                 (if (or (string-blank? id) (string-blank? name))
                     (nullable-none BoxType)
-                    (nullable-some (make-BoxType id name))))))))
+                    (nullable-some (make-BoxType id name))))))
+        (def (boxTypesFromCsvText (text : String)) : (MutableList BoxType)
+          (let ((lines (boxTypeCsvStringLines text)))
+            (for/fold ((items (mutable-list-empty BoxType)))
+                      ((i (in-range (int32 1) (list-size lines))))
+              (begin
+                (addNullableBoxType
+                  items
+                  (parseBoxTypeCsvLine (list-ref lines i)))
+                items))))))
 
     (typed-kotlin-file "com/sfb/ssdreview/OcrWord.kt"
       (typed-library (com sfb ssdreview)
@@ -9181,12 +9192,7 @@
        ""
        "    fun load(context: Context): List<BoxType> {"
        "        if (cacheLoaded) return cache"
-       "        val items = mutableListOf<BoxType>()"
-       "        context.assets.open(\"box_types.csv\").bufferedReader().useLines { lines ->"
-       "            lines.drop(1).forEach { line ->"
-       "                addNullableBoxType(items, parseBoxTypeCsvLine(line))"
-       "            }"
-       "        }"
+       "        val items = boxTypesFromCsvText(context.assets.open(\"box_types.csv\").bufferedReader().use { it.readText() })"
        "        cache = items"
        "        cacheLoaded = true"
        "        return items"