///|
/// Appends the native locale only when one was detected.
fn append_optional_locale_candidate(
target : Array[String],
locale : String?,
) -> Unit {
match locale {
Some(locale) => push_candidate(target, locale)
None => ()
}
}
///|
/// Returns the initial byte capacity used for the native locale buffer.
fn native_locale_initial_buffer_size() -> Int {
128
}
///|
/// Returns a conservative upper bound for locale buffer growth.
fn native_locale_max_buffer_size() -> Int {
4096
}
///|
/// Collects raw locale candidates from env vars and native APIs.
fn locale_raw_candidates_internal() -> Array[String] {
let result : Array[String] = []
append_env_locale_candidates(result)
append_optional_locale_candidate(result, native_system_locale())
result
}
///|
/// Decodes the native locale bytes when the FFI call succeeds.
fn decode_native_system_locale(buf : Bytes, written : Int) -> String? {
if written <= 0 || written > buf.length() {
None
} else {
Some(@utf8.decode(buf[:written])) catch {
_ => None
}
}
}
///|
/// Returns the next buffer size when the native read needs more space.
fn next_native_locale_buffer_capacity(capacity : Int, written : Int) -> Int? {
if written < capacity || capacity >= native_locale_max_buffer_size() {
None
} else {
Some(capacity * 2)
}
}
///|
/// Reads the current locale through the native shim using a growing buffer.
fn read_native_system_locale_with_capacity(capacity : Int) -> String? {
let buf = Bytes::new(capacity)
let written = native_system_locale_ffi(buf, capacity)
match next_native_locale_buffer_capacity(capacity, written) {
Some(next_capacity) =>
read_native_system_locale_with_capacity(next_capacity)
None => decode_native_system_locale(buf, written)
}
}
///|
/// Reads the current locale through the native shim.
fn native_system_locale() -> String? {
read_native_system_locale_with_capacity(native_locale_initial_buffer_size())
}
///|
/// Binds to the native function that writes the current locale tag.
///
/// The native side returns the byte count written on success, or the required
/// byte count when the provided buffer is too small.
#borrow(buf)
extern "c" fn native_system_locale_ffi(buf : Bytes, len : Int) -> Int = "sys_locale_native_current"