From e13c551c53e8a6f229a9f40328a99c44411ac4b5 Mon Sep 17 00:00:00 2001
From: Janne Mareike Koschinski <janne@kuschku.de>
Date: Thu, 3 Mar 2022 19:16:27 +0100
Subject: [PATCH] feat: split text formatter

---
 .../extensions/TextFormatterExtensions.kt     | 25 +++++++++++
 .../quasseldroid/util/format/TextFormatter.kt | 42 +++++--------------
 2 files changed, 35 insertions(+), 32 deletions(-)
 create mode 100644 app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt

diff --git a/app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt b/app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt
new file mode 100644
index 000000000..eeaba8ac3
--- /dev/null
+++ b/app/src/main/kotlin/de/justjanne/quasseldroid/util/extensions/TextFormatterExtensions.kt
@@ -0,0 +1,25 @@
+package de.justjanne.quasseldroid.util.extensions
+
+import android.text.Spanned
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.core.text.buildSpannedString
+import de.justjanne.quasseldroid.util.AnnotatedStringAppender
+import de.justjanne.quasseldroid.util.format.TextFormatter
+import java.util.*
+
+fun TextFormatter.format(
+  template: AnnotatedString,
+  vararg args: Any?,
+  locale: Locale = Locale.getDefault()
+): AnnotatedString = buildAnnotatedString {
+  formatBlocks(AnnotatedStringAppender(this), parseBlocks(template), args, locale)
+}
+
+fun TextFormatter.format(
+  template: Spanned,
+  vararg args: Any?,
+  locale: Locale = Locale.getDefault()
+): Spanned = buildSpannedString {
+  formatBlocks(this, parseBlocks(template), args, locale)
+}
diff --git a/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt b/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt
index 3d605faa9..858f258f8 100644
--- a/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt
+++ b/app/src/main/kotlin/de/justjanne/quasseldroid/util/format/TextFormatter.kt
@@ -16,38 +16,12 @@
 
 package de.justjanne.quasseldroid.util.format
 
-import android.text.Spanned
-import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.buildAnnotatedString
-import androidx.core.text.buildSpannedString
-import de.justjanne.quasseldroid.util.AnnotatedStringAppender
 import de.justjanne.quasseldroid.util.extensions.component6
 import de.justjanne.quasseldroid.util.extensions.component7
 import java.util.*
 import java.util.regex.Pattern
 
-/**
- * Provides [String.format] style functions that work with [Spanned] strings and preserve formatting.
- *
- * @author George T. Steel
- */
 object TextFormatter {
-  fun format(
-    template: AnnotatedString,
-    vararg args: Any?,
-    locale: Locale = Locale.getDefault()
-  ): AnnotatedString = buildAnnotatedString {
-    formatBlocks(AnnotatedStringAppender(this), parseBlocks(template), args, locale)
-  }
-
-  fun format(
-    template: Spanned,
-    vararg args: Any?,
-    locale: Locale = Locale.getDefault()
-  ): Spanned = buildSpannedString {
-    formatBlocks(this, parseBlocks(template), args, locale)
-  }
-
   fun format(
     template: String,
     vararg args: Any?,
@@ -56,7 +30,7 @@ object TextFormatter {
     formatBlocks(this, parseBlocks(template), args, locale)
   }
 
-  internal fun formatBlocks(
+  fun formatBlocks(
     target: Appendable,
     blocks: Sequence<FormatString>,
     args: Array<out Any?>,
@@ -67,10 +41,14 @@ object TextFormatter {
       when (block) {
         is FormatString.FixedValue -> target.append(block.content)
         is FormatString.FormatSpecifier -> {
-          val arg = when {
-              block.argumentIndex != null -> args[block.argumentIndex - 1]
-              block.flags.orEmpty().contains(FLAG_REUSE_ARGUMENT) -> args[argIndex]
-              else -> args[argIndex++]
+          val index = when {
+            block.argumentIndex != null -> block.argumentIndex - 1
+            block.flags.orEmpty().contains(FLAG_REUSE_ARGUMENT) -> argIndex
+            else -> argIndex++
+          }
+          val arg = if (index in 0..args.size) args[index] else {
+            target.append(block.toFormatSpecifier())
+            continue
           }
 
           if (block.conversion.lowercaseChar() == TYPE_STRING) {
@@ -109,7 +87,7 @@ object TextFormatter {
     }
   }
 
-  internal fun parseBlocks(template: CharSequence) = sequence {
+  fun parseBlocks(template: CharSequence) = sequence {
     var index = 0
     while (index < template.length) {
       val match = FORMAT_SEQUENCE.toRegex().find(template, index)
-- 
GitLab