-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
extended Locale to support "script" and "extensions"
- Loading branch information
1 parent
d2371e0
commit b0dae4d
Showing
7 changed files
with
749 additions
and
239 deletions.
There are no files selected for viewing
96 changes: 96 additions & 0 deletions
96
i18n4k-core/src/commonMain/kotlin/de/comahe/i18n4k/DefaultLocaleImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package de.comahe.i18n4k | ||
|
||
import kotlinx.collections.immutable.ImmutableMap | ||
import kotlinx.collections.immutable.persistentMapOf | ||
|
||
/** Default implementation for [Locale] for non JVM targets */ | ||
@Suppress("MemberVisibilityCanBePrivate", "unused") | ||
class DefaultLocaleImpl( | ||
private val language: String, | ||
private val script: String, | ||
private val country: String, | ||
private val variant: String, | ||
private val extensions: ImmutableMap<Char, String>, | ||
) { | ||
constructor( | ||
language: String | ||
) : this(language, "", "") | ||
|
||
constructor( | ||
language: String, | ||
country: String, | ||
) : this(language, country, "") | ||
|
||
|
||
constructor( | ||
language: String, | ||
country: String, | ||
variant: String, | ||
) : this(language, "", country, variant, persistentMapOf()) | ||
|
||
fun getLanguage(): String = language | ||
fun getScript(): String = script | ||
fun getCountry(): String = country | ||
fun getVariant(): String = variant | ||
|
||
|
||
fun hasExtensions(): Boolean = extensions.isNotEmpty() | ||
|
||
fun stripExtensions(): DefaultLocaleImpl { | ||
if (hasExtensions()) | ||
return DefaultLocaleImpl(language, script, country, variant, persistentMapOf()) | ||
return this | ||
} | ||
|
||
fun getExtension(key: Char): String? = extensions[key] | ||
|
||
fun getExtensionKeys(): Set<Char> = extensions.keys | ||
|
||
override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (other !is DefaultLocaleImpl) return false | ||
|
||
if (language != other.language) return false | ||
if (script != other.script) return false | ||
if (country != other.country) return false | ||
if (variant != other.variant) return false | ||
if (extensions != other.extensions) return false | ||
|
||
return true | ||
} | ||
|
||
override fun hashCode(): Int { | ||
var result = language.hashCode() | ||
result = 31 * result + script.hashCode() | ||
result = 31 * result + country.hashCode() | ||
result = 31 * result + variant.hashCode() | ||
result = 31 * result + extensions.hashCode() | ||
return result | ||
} | ||
|
||
override fun toString(): String { | ||
return toLocaleTag(language, script, country, variant, extensions) | ||
} | ||
} | ||
|
||
/** Default implementation for [createLocale] for non JVM targets */ | ||
fun createDefaultLocaleImpl( | ||
language: String, | ||
script: String?, | ||
country: String?, | ||
variant: String?, | ||
extensions: Map<Char, String>? | ||
): DefaultLocaleImpl { | ||
val extensionsBuilder = persistentMapOf<Char, String>().builder() | ||
extensions?.forEach { (key, value) -> | ||
extensionsBuilder[key.lowercaseChar()] = value.lowercase() | ||
} | ||
|
||
return DefaultLocaleImpl( | ||
language.trim().lowercase(), | ||
script?.trim()?.capitalize() ?: "", | ||
country?.trim()?.uppercase() ?: "", | ||
variant?.trim()?.lowercase() ?: "", | ||
extensionsBuilder.build() | ||
) | ||
} |
108 changes: 97 additions & 11 deletions
108
i18n4k-core/src/commonMain/kotlin/de/comahe/i18n4k/Locale.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,124 @@ | ||
package de.comahe.i18n4k | ||
|
||
/** Class representing a locale */ | ||
expect class Locale( | ||
/** See [Locale.getLanguage] */ | ||
language: String, | ||
/** See [Locale.getCountry] */ | ||
country: String, | ||
/** See [Locale.getVariant] */ | ||
variant: String | ||
) { | ||
|
||
/** Class representing a locale */ | ||
expect class Locale { | ||
@Deprecated( | ||
message = "Use `createLocale`", | ||
replaceWith = ReplaceWith("createLocale(language)"), | ||
level = DeprecationLevel.WARNING | ||
) | ||
constructor( | ||
/** See [Locale.getLanguage] */ | ||
language: String | ||
) | ||
|
||
@Deprecated( | ||
message = "Use `createLocale`", | ||
replaceWith = ReplaceWith("createLocale(language, null, country)"), | ||
level = DeprecationLevel.WARNING | ||
) | ||
constructor( | ||
/** See [Locale.getLanguage] */ | ||
language: String, | ||
/** See [Locale.getCountry] */ | ||
country: String | ||
) | ||
|
||
@Deprecated( | ||
message = "Use `createLocale`", | ||
replaceWith = ReplaceWith("createLocale(language, null, country, variant)"), | ||
level = DeprecationLevel.WARNING | ||
) | ||
constructor ( | ||
/** See [Locale.getLanguage] */ | ||
language: String, | ||
/** See [Locale.getCountry] */ | ||
country: String, | ||
/** See [Locale.getVariant] */ | ||
variant: String | ||
) | ||
|
||
|
||
/** Language code. Should be a [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) */ | ||
/** | ||
* Language code. | ||
* | ||
* Should be a | ||
* [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). | ||
* | ||
* Will be lowercase. | ||
*/ | ||
fun getLanguage(): String | ||
|
||
/**country/region code for this locale, which should either be the empty string, an uppercase ISO 3166 2-letter code, or a UN M.49 3-digit code. */ | ||
/** | ||
* Returns the script for this locale, which should either be the empty | ||
* string or an "ISO 15924 4"-letter script code. | ||
* | ||
* The first letter is uppercase and the rest are lowercase, for example, | ||
* 'Latn', 'Cyrl'. | ||
*/ | ||
fun getScript(): String | ||
|
||
/** | ||
* country/region code for this locale, which should either be the empty | ||
* string, an uppercase ISO 3166 2-letter code, or a UN M.49 3-digit code. | ||
*/ | ||
fun getCountry(): String | ||
|
||
/** the variant code for this locale. Can be an empty string */ | ||
fun getVariant(): String | ||
|
||
/** Returns `true` if this `Locale` has any extensions. */ | ||
fun hasExtensions(): Boolean | ||
|
||
/** | ||
* Returns a copy of this (or this itself) `Locale` with no extensions. | ||
* | ||
* If this `Locale` has no extensions, this `Locale` is returned. | ||
*/ | ||
fun stripExtensions(): Locale | ||
|
||
/** | ||
* Returns the extension (or private use) value associated with the | ||
* specified key, or null if there is no extension associated with the key. | ||
* | ||
* To be well-formed, the key must be one of `[0-9A-Za-z]`. | ||
* | ||
* Keys are case-insensitive, so for example, 'z' and 'Z' represent the | ||
* same extension. | ||
* | ||
* @param key the extension key | ||
* @return The extension, or null if this locale defines no extension for | ||
* the specified key. | ||
* @throws IllegalArgumentException if key is not well-formed | ||
*/ | ||
fun getExtension(key: Char): String? | ||
|
||
/** | ||
* Returns the set of extension keys associated with this locale, or the | ||
* empty set if it has no extensions. | ||
* | ||
* The returned set is unmodifiable. | ||
* | ||
* The keys will all be lower-case. | ||
*/ | ||
fun getExtensionKeys(): Set<Char> | ||
} | ||
|
||
/** | ||
* Create a local with extensions. | ||
* | ||
* Regarding extensions see: | ||
* * [language-tags](https://www.w3.org/International/articles/language-tags/#extension) | ||
* * [rfc5646](https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.6) | ||
*/ | ||
expect fun createLocale( | ||
language: String, | ||
script: String? = null, | ||
country: String? = null, | ||
variant: String? = null, | ||
extensions: Map<Char, String>? = null, | ||
): Locale | ||
|
||
/** The current locale of the system or user */ | ||
expect val systemLocale: Locale |
Oops, something went wrong.