From bf6177d43713ca5dc905888a600ede07047b0563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Thu, 11 Aug 2022 12:36:41 +0200 Subject: [PATCH] Use core-foundation-sys instead of core-foundation iana-time-zone is used by [chrono], and chrono is (optionally) used by [core-foundation]. So if iana-time-zone uses core-foundation, this results in a circular dependency. This PR replaces core-foundation by [core-foundation-sys], which breaks the circular dependency. [chrono]: https://crates.io/crates/chrono [core-foundation]: https://crates.io/crates/core-foundation [core-foundation-sys]: https://crates.io/crates/core-foundation-sys --- Cargo.toml | 2 +- src/tz_macos.rs | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d30309b..59f1636 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ fallback = [] android_system_properties = "0.1.4" [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] -core-foundation = "0.9" +core-foundation-sys = "0.8.3" [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3.9", features = ["activation", "combaseapi", "objbase", "roapi", "winerror", "winstring"] } diff --git a/src/tz_macos.rs b/src/tz_macos.rs index 3d3e65a..a42c00a 100644 --- a/src/tz_macos.rs +++ b/src/tz_macos.rs @@ -1,5 +1,41 @@ +use core_foundation_sys::base::{CFRelease, CFTypeRef}; +use core_foundation_sys::string::{kCFStringEncodingUTF8, CFStringGetCStringPtr}; +use core_foundation_sys::timezone::{CFTimeZoneCopySystem, CFTimeZoneGetName}; + pub(crate) fn get_timezone_inner() -> Result { - Ok(core_foundation::timezone::CFTimeZone::system() - .name() - .to_string()) + unsafe { + Dropping::new(CFTimeZoneCopySystem()) + .and_then(|tz| Dropping::new(CFTimeZoneGetName(tz.0))) + .and_then(|name| { + let name = CFStringGetCStringPtr(name.0, kCFStringEncodingUTF8); + if name.is_null() { + None + } else { + Some(name) + } + }) + .and_then(|name| std::ffi::CStr::from_ptr(name).to_str().ok()) + .map(|name| name.to_owned()) + .ok_or(crate::GetTimezoneError::OsError) + } +} + +struct Dropping(*const T); + +impl Drop for Dropping { + #[inline] + fn drop(&mut self) { + unsafe { CFRelease(self.0 as CFTypeRef) }; + } +} + +impl Dropping { + #[inline] + unsafe fn new(v: *const T) -> Option { + if v.is_null() { + None + } else { + Some(Self(v)) + } + } }