Lower typed URL encoding to Kotlin

ober

1bc04b91311896a4b0526600040c67f803a836fd

diff --git a/lib/jerboa/typed/checker.ss b/lib/jerboa/typed/checker.ss
index 372a799..2d3e9ec 100644
--- a/lib/jerboa/typed/checker.ss
+++ b/lib/jerboa/typed/checker.ss
@@ -460,6 +460,9 @@
       (cons 'string-blank?
             (make-typed-call-sig (list 'String) 'Bool '()
               'jvm-string-blank '()))
+      (cons 'url-encode-utf8
+            (make-typed-call-sig (list 'String) 'String '()
+              'jvm-url-encode-utf8 '()))
       ;; crypto primitives — FFI to vetted RustCrypto crates, never reimplemented.
       ;; Each carries kind 'crypto-prim and an info `prim` the emitter dispatches
       ;; on; the Rust block they emit references the crate (sha2/hmac/hkdf) that
diff --git a/lib/jerboa/typed/kotlin/lower.ss b/lib/jerboa/typed/kotlin/lower.ss
index 5f0f5f6..5aaca8c 100644
--- a/lib/jerboa/typed/kotlin/lower.ss
+++ b/lib/jerboa/typed/kotlin/lower.ss
@@ -278,6 +278,10 @@
          (make-kt-member-call (car args) 'endsWith (cdr args))]
         [(jvm-string-blank)
          (make-kt-member-call (car args) 'isBlank '())]
+        [(jvm-url-encode-utf8)
+         (make-kt-call
+           (make-kt-name '(java net URLEncoder encode))
+           (list (car args) (make-kt-lit 'String "UTF-8")))]
         [(jvm-float-array)
          (make-kt-call (kt-name1 'floatArrayOf) args)]
         [(jvm-float-array-ref)
diff --git a/tests/test-typed-kotlin.ss b/tests/test-typed-kotlin.ss
index fdd0d89..2e7199c 100644
--- a/tests/test-typed-kotlin.ss
+++ b/tests/test-typed-kotlin.ss
@@ -420,6 +420,8 @@
          " "))
      (def (compact (value : String)) : String
        (string-filter-letter-or-digit (string-lowercase value)))
+     (def (encoded (value : String)) : String
+       (url-encode-utf8 value))
      (def (shouldReplaceOcrLabel (label : String) (status : String) (notes : String)) : Bool
        (let ((text (string-trim label)))
          (if (string-blank? text)
@@ -441,6 +443,8 @@
   ".trim()")
 (test-contains "String filter letter-or-digit lowers to Kotlin filter lambda" ocr-string-kotlin
   "value.lowercase().filter({ ch -> ch.isLetterOrDigit() })")
+(test-contains "URL encode UTF-8 lowers to Java URLEncoder" ocr-string-kotlin
+  "java.net.URLEncoder.encode(value, \"UTF-8\")")
 (test-contains "String endsWith lowers to Kotlin endsWith" ocr-string-kotlin
   "text.endsWith(\"?\")")
 (test-contains "String regex matches lowers to Kotlin Regex matches" ocr-string-kotlin