Scala borrows Java String methods like toUpperCase/toLowerCase.
However, the way it does so is not very consistent:
- Scala on JVM stick close to Java semantics, thus:
toUpperCase()
is locale-sensitive and sticks to default locale (giving you infamous i → İ problem in Turkish locale)- to avoid that and keep locale-insensitive (en_US / C-like) process, you need to specifically do
toUpperCase(Locale.ROOT)
- Scala.JS does not implement a concept of Locale, thus:
toUpperCase()
works in locale-insensitive mannertoUpperCase(Locale locale)
method is effectively not available in ScalaJS
How do I implement locale-insensitive case conversion that will work in Scala on both JVM/JS?
I can think of several ways, all of them as ugly:
Method 1: My own implementation
Implement my own toUpperCase
for specifically 26 ASCII characters of English alphabet.
Method 1.1: My own implementation using Scala chars
Basically the same, but at least reuse Scala toUpper to convert individual chars.
Method 2: Interface
Implement something like
trait CaseChangeOps {
def toUpperCase(s: String): String
}
object Main {
var caseChanger: CaseChanger
}
// whenever I want to use it, do it like that:
Main.caseChanger.toUpperCase("like this") // => "LIKE THIS"
in shared code, and then in JS have:
object CaseChangerJs {
def toUpperCase(s: String): String = s.toUpperCase
}
object MainJs {
Main.caseChanger = CaseChangerJs
}
... and in JVM:
object CaseChangerJvm {
def toUpperCase(s: String): String = s.toUpperCase(Locale.ROOT)
}
object MainJvm {
Main.caseChanger = CaseChangerJvm
}
Method 3: bring external scala-java-locales
There is a distinct 3rd party library scala-java-locales, which is listed as ScalaJS-compatible, and can be used to augument ScalaJS.
Looks like a massive overkill, though, as I literally only need locale-insensitive case conversions, not the whole thing for all possible locales.
Any better ideas?