Skip to content

Instantly share code, notes, and snippets.

@green-nick
Last active April 1, 2021 20:32
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save green-nick/e32f8b9309a89070de38e299a21932eb to your computer and use it in GitHub Desktop.
Save green-nick/e32f8b9309a89070de38e299a21932eb to your computer and use it in GitHub Desktop.
Wrapper for strings without Android-dependency
package ...
private val identityMap: (String) -> String = { it }
sealed class LocalizedString
data class ResourceString(
val id: Int,
val quantity: Int? = null,
val args: List<Any> = emptyList(),
val map: (String) -> String = identityMap
) : LocalizedString()
data class Wrapped(val stringValue: String) : LocalizedString()
data class CompoundString(val strings: List<LocalizedString>) : LocalizedString()
val String.wrap get() = Wrapped(this)
operator fun LocalizedString.plus(another: String): CompoundString = this + another.wrap
operator fun CompoundString.plus(another: String): CompoundString = this + another.wrap
operator fun LocalizedString.plus(another: LocalizedString): CompoundString =
when (this) {
is CompoundString -> when (another) {
is CompoundString -> CompoundString(this.strings + another.strings)
else -> CompoundString(this.strings + another)
}
else -> when (another) {
is CompoundString -> CompoundString(listOf(this) + another.strings)
else -> CompoundString(listOf(this, another))
}
}
operator fun LocalizedString.plus(another: CompoundString): CompoundString =
CompoundString(listOf(this) + another.strings)
operator fun CompoundString.plus(another: LocalizedString): CompoundString =
CompoundString(this.strings + another)
operator fun CompoundString.plus(another: CompoundString): CompoundString =
CompoundString(this.strings + another.strings)
package ...
import android.content.Context
operator fun LocalizedString.get(context: Context) = unwrap(context)
fun LocalizedString.unwrap(
context: Context
): CharSequence = when (this) {
is Wrapped -> stringValue
is CompoundString -> strings.joinToString(separator = "") { it.unwrap(context) }
is ResourceString -> map(
getStringFromResources(
context,
id,
quantity,
args.map { if (it is LocalizedString) it.unwrap(context) else it }
)
)
}
private fun getStringFromResources(
context: Context,
id: Int,
quantity: Int?,
args: List<Any>
): String = if (quantity == null) {
context.getString(id, *args.toTypedArray())
} else {
context.resources.getQuantityString(id, quantity, *args.toTypedArray())
}
@green-nick
Copy link
Author

"TypedString" sounds better

@green-nick
Copy link
Author

Create some pre-defined mappers, e.g. capitalzie, decapitalize

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment