variant_offset.rs (7605B)
1 // This file is part of ICU4X. For terms of use, please see the file 2 // called LICENSE at the top level of the ICU4X source tree 3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). 4 5 #[diplomat::bridge] 6 #[diplomat::abi_rename = "icu4x_{0}_mv1"] 7 #[diplomat::attr(auto, namespace = "icu4x")] 8 pub mod ffi { 9 use alloc::boxed::Box; 10 11 #[cfg(feature = "buffer_provider")] 12 use crate::unstable::errors::ffi::DataError; 13 #[cfg(feature = "buffer_provider")] 14 use crate::unstable::provider::ffi::DataProvider; 15 use crate::unstable::{ 16 date::ffi::IsoDate, errors::ffi::TimeZoneInvalidOffsetError, time::ffi::Time, 17 timezone::ffi::TimeZone, 18 }; 19 20 #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculator, Struct)] 21 #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculatorBorrowed, Struct, hidden)] 22 #[diplomat::opaque] 23 pub struct VariantOffsetsCalculator(pub icu_time::zone::VariantOffsetsCalculator); 24 25 #[diplomat::opaque] 26 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct)] 27 pub struct UtcOffset(pub(crate) icu_time::zone::UtcOffset); 28 29 #[diplomat::out] 30 #[diplomat::rust_link(icu::time::zone::VariantOffsets, Struct)] 31 #[diplomat::rust_link(icu::time::zone::VariantOffsets::from_standard, FnInStruct, hidden)] // out struct 32 pub struct VariantOffsets { 33 pub standard: Box<UtcOffset>, 34 pub daylight: Option<Box<UtcOffset>>, 35 } 36 37 impl UtcOffset { 38 /// Creates an offset from seconds. 39 /// 40 /// Errors if the offset seconds are out of range. 41 #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_seconds, FnInStruct)] 42 #[diplomat::rust_link( 43 icu::time::zone::UtcOffset::from_seconds_unchecked, 44 FnInStruct, 45 hidden 46 )] 47 #[diplomat::attr(all(supports = named_constructors, supports = fallible_constructors), named_constructor = "from_seconds")] 48 pub fn from_seconds(seconds: i32) -> Result<Box<UtcOffset>, TimeZoneInvalidOffsetError> { 49 Ok(Box::new(Self(icu_time::zone::UtcOffset::try_from_seconds( 50 seconds, 51 )?))) 52 } 53 54 /// Creates an offset from a string. 55 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 56 #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_str, FnInStruct)] 57 #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_utf8, FnInStruct, hidden)] 58 #[diplomat::rust_link(icu::time::zone::UtcOffset::from_str, FnInStruct, hidden)] 59 #[diplomat::attr(all(supports = named_constructors, supports = fallible_constructors), named_constructor = "from_string")] 60 #[diplomat::demo(default_constructor)] 61 pub fn from_string(offset: &DiplomatStr) -> Result<Box<Self>, TimeZoneInvalidOffsetError> { 62 icu_time::zone::UtcOffset::try_from_utf8(offset) 63 .map_err(|_| TimeZoneInvalidOffsetError) 64 .map(Self) 65 .map(Box::new) 66 } 67 68 /// Returns the value as offset seconds. 69 #[diplomat::rust_link(icu::time::TimeZoneInfo::offset, FnInStruct)] 70 #[diplomat::rust_link(icu::time::zone::UtcOffset::to_seconds, FnInStruct)] 71 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 72 #[diplomat::attr(auto, getter)] 73 pub fn seconds(&self) -> i32 { 74 self.0.to_seconds() 75 } 76 77 /// Returns whether the offset is positive. 78 #[diplomat::rust_link(icu::time::zone::UtcOffset::is_non_negative, FnInStruct)] 79 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 80 #[diplomat::attr(auto, getter)] 81 pub fn is_non_negative(&self) -> bool { 82 self.0.is_non_negative() 83 } 84 85 /// Returns whether the offset is zero. 86 #[diplomat::rust_link(icu::time::zone::UtcOffset::is_zero, FnInStruct)] 87 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 88 #[diplomat::attr(auto, getter)] 89 pub fn is_zero(&self) -> bool { 90 self.0.is_zero() 91 } 92 93 /// Returns the hours part of the offset. 94 #[diplomat::rust_link(icu::time::zone::UtcOffset::hours_part, FnInStruct)] 95 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 96 #[diplomat::attr(auto, getter)] 97 pub fn hours_part(&self) -> i32 { 98 self.0.hours_part() 99 } 100 101 /// Returns the minutes part of the offset. 102 #[diplomat::rust_link(icu::time::zone::UtcOffset::minutes_part, FnInStruct)] 103 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 104 #[diplomat::attr(auto, getter)] 105 pub fn minutes_part(&self) -> u32 { 106 self.0.minutes_part() 107 } 108 109 /// Returns the seconds part of the offset. 110 #[diplomat::rust_link(icu::time::zone::UtcOffset::seconds_part, FnInStruct)] 111 #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)] 112 #[diplomat::attr(auto, getter)] 113 pub fn seconds_part(&self) -> u32 { 114 self.0.seconds_part() 115 } 116 } 117 118 impl VariantOffsetsCalculator { 119 /// Construct a new [`VariantOffsetsCalculator`] instance using compiled data. 120 #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculator::new, FnInStruct)] 121 #[diplomat::rust_link( 122 icu::time::zone::VariantOffsetsCalculatorBorrowed::new, 123 FnInStruct, 124 hidden 125 )] 126 #[diplomat::attr(auto, constructor)] 127 #[cfg(feature = "compiled_data")] 128 pub fn create() -> Box<VariantOffsetsCalculator> { 129 Box::new(VariantOffsetsCalculator( 130 icu_time::zone::VariantOffsetsCalculator::new().static_to_owned(), 131 )) 132 } 133 /// Construct a new [`VariantOffsetsCalculator`] instance using a particular data source. 134 #[diplomat::rust_link(icu::time::zone::VariantOffsetsCalculator::new, FnInStruct)] 135 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")] 136 #[cfg(feature = "buffer_provider")] 137 pub fn create_with_provider( 138 provider: &DataProvider, 139 ) -> Result<Box<VariantOffsetsCalculator>, DataError> { 140 Ok(Box::new(VariantOffsetsCalculator( 141 icu_time::zone::VariantOffsetsCalculator::try_new_with_buffer_provider( 142 provider.get()?, 143 )?, 144 ))) 145 } 146 147 #[diplomat::rust_link( 148 icu::time::zone::VariantOffsetsCalculatorBorrowed::compute_offsets_from_time_zone_and_name_timestamp, 149 FnInStruct 150 )] 151 pub fn compute_offsets_from_time_zone_and_date_time( 152 &self, 153 time_zone: &TimeZone, 154 local_date: &IsoDate, 155 local_time: &Time, 156 ) -> Option<VariantOffsets> { 157 let icu_time::zone::VariantOffsets { 158 standard, daylight, .. 159 } = self 160 .0 161 .as_borrowed() 162 .compute_offsets_from_time_zone_and_name_timestamp( 163 time_zone.0, 164 icu_time::zone::ZoneNameTimestamp::from_date_time_iso(icu_time::DateTime { 165 date: local_date.0, 166 time: local_time.0, 167 }), 168 )?; 169 170 Some(VariantOffsets { 171 standard: Box::new(UtcOffset(standard)), 172 daylight: daylight.map(UtcOffset).map(Box::new), 173 }) 174 } 175 } 176 }