// This file is part of ICU4X. For terms of use, please see the file // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). #[diplomat::bridge] #[diplomat::abi_rename = "icu4x_{0}_mv1"] pub mod ffi { use alloc::boxed::Box; #[cfg(feature = "buffer_provider")] use crate::unstable::errors::ffi::DataError; #[cfg(feature = "buffer_provider")] use crate::unstable::provider::ffi::DataProvider; use crate::unstable::{ date::ffi::IsoDate, errors::ffi::TimeZoneInvalidOffsetError, time::ffi::Time, timezone::ffi::TimeZone, }; #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculator, Struct)] #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculatorBorrowed, Struct, hidden)] #[diplomat::opaque] #[deprecated(note = "this API is a bad approximation of a time zone database")] #[allow(deprecated)] pub struct VariantOffsetsCalculator(pub icu_time::zone::VariantOffsetsCalculator); #[diplomat::opaque] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct)] pub struct UtcOffset(pub(crate) icu_time::zone::UtcOffset); #[diplomat::out] #[diplomat::rust_link(icu::time::zone::VariantOffsets, Struct)] #[diplomat::rust_link(icu::time::zone::VariantOffsets::from_standard, FnInStruct, hidden)] // out struct pub struct VariantOffsets { pub standard: Box, pub daylight: Option>, } impl UtcOffset { /// Creates an offset from seconds. /// /// Errors if the offset seconds are out of range. #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_seconds, FnInStruct)] #[diplomat::rust_link( icu::time::zone::UtcOffset::from_seconds_unchecked, FnInStruct, hidden )] #[diplomat::attr(all(supports = named_constructors, supports = fallible_constructors), named_constructor = "from_seconds")] pub fn from_seconds(seconds: i32) -> Result, TimeZoneInvalidOffsetError> { Ok(Box::new(Self(icu_time::zone::UtcOffset::try_from_seconds( seconds, )?))) } /// Creates an offset from a string. #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_str, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_utf8, FnInStruct, hidden)] #[diplomat::rust_link(icu::time::zone::UtcOffset::from_str, FnInStruct, hidden)] #[diplomat::attr(all(supports = named_constructors, supports = fallible_constructors), named_constructor = "from_string")] #[diplomat::demo(default_constructor)] pub fn from_string(offset: &DiplomatStr) -> Result, TimeZoneInvalidOffsetError> { icu_time::zone::UtcOffset::try_from_utf8(offset) .map_err(|_| TimeZoneInvalidOffsetError) .map(Self) .map(Box::new) } /// Returns the value as offset seconds. #[diplomat::rust_link(icu::time::TimeZoneInfo::offset, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset::to_seconds, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::attr(auto, getter)] pub fn seconds(&self) -> i32 { self.0.to_seconds() } /// Returns whether the offset is positive. #[diplomat::rust_link(icu::time::zone::UtcOffset::is_non_negative, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::attr(auto, getter)] pub fn is_non_negative(&self) -> bool { self.0.is_non_negative() } /// Returns whether the offset is zero. #[diplomat::rust_link(icu::time::zone::UtcOffset::is_zero, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::attr(auto, getter)] pub fn is_zero(&self) -> bool { self.0.is_zero() } /// Returns the hours part of the offset. #[diplomat::rust_link(icu::time::zone::UtcOffset::hours_part, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::attr(auto, getter)] pub fn hours_part(&self) -> i32 { self.0.hours_part() } /// Returns the minutes part of the offset. #[diplomat::rust_link(icu::time::zone::UtcOffset::minutes_part, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::attr(auto, getter)] pub fn minutes_part(&self) -> u32 { self.0.minutes_part() } /// Returns the seconds part of the offset. #[diplomat::rust_link(icu::time::zone::UtcOffset::seconds_part, FnInStruct)] #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] #[diplomat::attr(auto, getter)] pub fn seconds_part(&self) -> u32 { self.0.seconds_part() } } #[allow(deprecated)] impl VariantOffsetsCalculator { /// Construct a new [`VariantOffsetsCalculator`] instance using compiled data. #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculator::new, FnInStruct)] #[diplomat::rust_link( icu::time::zone::VariantOffsetsCalculatorBorrowed::new, FnInStruct, hidden )] #[diplomat::attr(auto, constructor)] #[cfg(feature = "compiled_data")] pub fn create() -> Box { Box::new(VariantOffsetsCalculator( icu_time::zone::VariantOffsetsCalculator::new().static_to_owned(), )) } /// Construct a new [`VariantOffsetsCalculator`] instance using a particular data source. #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculator::new, FnInStruct)] #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")] #[cfg(feature = "buffer_provider")] pub fn create_with_provider( provider: &DataProvider, ) -> Result, DataError> { Ok(Box::new(VariantOffsetsCalculator( icu_time::zone::VariantOffsetsCalculator::try_new_with_buffer_provider( provider.get()?, )?, ))) } #[diplomat::rust_link( icu::time::zone::VariantOffsetsCalculatorBorrowed::compute_offsets_from_time_zone_and_name_timestamp, FnInStruct )] #[allow(deprecated)] // clean up in 3.0 pub fn compute_offsets_from_time_zone_and_date_time( &self, time_zone: &TimeZone, utc_date: &IsoDate, utc_time: &Time, ) -> Option { let icu_time::zone::VariantOffsets { standard, daylight, .. } = self .0 .as_borrowed() .compute_offsets_from_time_zone_and_name_timestamp( time_zone.0, icu_time::zone::ZoneNameTimestamp::from_date_time_iso(icu_time::DateTime { date: utc_date.0, time: utc_time.0, }), )?; Some(VariantOffsets { standard: Box::new(UtcOffset(standard)), daylight: daylight.map(UtcOffset).map(Box::new), }) } #[diplomat::rust_link( icu::time::zone::VariantOffsetsCalculatorBorrowed::compute_offsets_from_time_zone_and_name_timestamp, FnInStruct )] #[diplomat::rust_link( icu::time::zone::ZoneNameTimestamp::from_zoned_date_time_iso, FnInStruct, hidden )] #[diplomat::rust_link( icu::time::ZonedDateTime::from_epoch_milliseconds_and_utc_offset, FnInStruct, hidden )] pub fn compute_offsets_from_time_zone_and_timestamp( &self, time_zone: &TimeZone, timestamp: i64, ) -> Option { let icu_time::zone::VariantOffsets { standard, daylight, .. } = self .0 .as_borrowed() .compute_offsets_from_time_zone_and_name_timestamp( time_zone.0, icu_time::zone::ZoneNameTimestamp::from_zoned_date_time_iso( icu_time::ZonedDateTime::from_epoch_milliseconds_and_utc_offset( timestamp, icu_time::zone::UtcOffset::zero(), ), ), )?; Some(VariantOffsets { standard: Box::new(UtcOffset(standard)), daylight: daylight.map(UtcOffset).map(Box::new), }) } } }