#[repr(C)] struct __CFArray(c_void); type CFArrayRef = *const __CFArray;
#[repr(C)] struct __CFString(c_void); type CFStringRef = *const __CFString;
// Most of these definitions come from `core-foundation-sys`, but we want this crate // to be `no_std` and `core-foundation-sys` isn't currently. #[link(name = "CoreFoundation", kind = "framework")] extern"C" { fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex; fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *const c_void;
#[allow(clippy::as_conversions)]
core::iter::from_fn(move || unsafe { let (langs, num_langs) = preferred_langs.as_ref()?;
// 0 to N-1 inclusive if idx >= *num_langs { return None;
}
// SAFETY: The current index has been checked that its still within bounds of the array. // XXX: We don't retain the strings because we know we have total ownership of the backing array. let locale = CFArrayGetValueAtIndex(langs.0, idx) as CFStringRef;
idx += 1;
// SAFETY: `locale` is a valid CFString pointer because the array will always contain a value. let str_len = CFStringGetLength(locale);
let range = CFRange {
location: 0,
length: str_len,
};
letmut capacity = 0; // SAFETY: // - `locale` is a valid CFString // - The supplied range is within the length of the string. // - `capacity` is writable. // Passing NULL and `0` is correct for the buffer to get the // encoded output length.
CFStringGetBytes(
locale,
range,
kCFStringEncodingUTF8, 0, falseas Boolean,
core::ptr::null_mut(), 0,
&mut capacity,
);
// Guard against a zero-sized allocation, if that were to somehow occur. if capacity == 0 { return None;
}
// Note: This is the number of bytes (u8) that will be written to // the buffer, not the number of codepoints they would contain. letmut buffer = Vec::with_capacity(capacity as usize);
// SAFETY: // - `locale` is a valid CFString // - The supplied range is within the length of the string. // - `buffer` is writable and has sufficent capacity to receive the data. // - `maxBufLen` is correctly based on `buffer`'s available capacity. // - `out_len` is writable. letmut out_len = 0;
CFStringGetBytes(
locale,
range,
kCFStringEncodingUTF8, 0, falseas Boolean,
buffer.as_mut_ptr(),
capacity as CFIndex,
&mut out_len,
);
// Sanity check that both calls to `CFStringGetBytes` // were equivalent. If they weren't, the system is doing // something very wrong...
assert!(out_len <= capacity);
// SAFETY: The system has written `out_len` elements, so they are // initialized and inside the buffer's capacity bounds.
buffer.set_len(out_len as usize);
// This should always contain UTF-8 since we told the system to // write UTF-8 into the buffer, but the value is small enough that // using `from_utf8_unchecked` isn't worthwhile.
String::from_utf8(buffer).ok()
})
}
fn get_languages() -> Option<(CFArray, CFIndex)> { unsafe { // SAFETY: This function is safe to call and has no invariants. Any value inside the // array will be owned by us. let langs = CFLocaleCopyPreferredLanguages(); if !langs.is_null() { let langs = CFArray(langs); // SAFETY: The returned array is a valid CFArray object. let count = CFArrayGetCount(langs.0); if count != 0 {
Some((langs, count))
} else {
None
}
} else {
None
}
}
}
struct CFArray(CFArrayRef);
impl Drop for CFArray { fn drop(&mutself) { // SAFETY: This wrapper contains a valid CFArray. unsafe { CFRelease(self.0.cast()) }
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.