• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::errors::ffi::DataError;
13     #[cfg(feature = "buffer_provider")]
14     use crate::provider::ffi::DataProvider;
15     use crate::{
16         date::ffi::IsoDate, errors::ffi::TimeZoneInvalidOffsetError, time::ffi::Time,
17         timezone::ffi::TimeZone,
18     };
19 
20     #[diplomat::rust_link(icu::time::zone::UtcOffsetCalculator, Struct)]
21     #[diplomat::opaque]
22     pub struct UtcOffsetCalculator(pub icu_time::zone::UtcOffsetCalculator);
23 
24     #[diplomat::opaque]
25     #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct)]
26     pub struct UtcOffset(pub(crate) icu_time::zone::UtcOffset);
27 
28     #[diplomat::out]
29     #[diplomat::rust_link(icu::time::zone::UtcOffsets, Struct)]
30     pub struct UtcOffsets {
31         pub standard: Box<UtcOffset>,
32         pub daylight: Option<Box<UtcOffset>>,
33     }
34 
35     impl UtcOffset {
36         /// Creates an offset from seconds.
37         ///
38         /// Errors if the offset seconds are out of range.
39         #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_seconds, FnInStruct)]
40         #[diplomat::rust_link(
41             icu::time::zone::UtcOffset::from_seconds_unchecked,
42             FnInStruct,
43             hidden
44         )]
45         #[diplomat::attr(auto, named_constructor = "from_seconds")]
from_seconds(seconds: i32) -> Result<Box<UtcOffset>, TimeZoneInvalidOffsetError>46         pub fn from_seconds(seconds: i32) -> Result<Box<UtcOffset>, TimeZoneInvalidOffsetError> {
47             Ok(Box::new(Self(icu_time::zone::UtcOffset::try_from_seconds(
48                 seconds,
49             )?)))
50         }
51 
52         /// Creates an offset from eighths of an hour.
53         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
54         #[diplomat::rust_link(icu::time::zone::UtcOffset::from_eighths_of_hour, FnInStruct)]
55         #[diplomat::attr(auto, named_constructor = "from_eights_of_hour")]
from_eighths_of_hour(eighths_of_hour: i8) -> Box<Self>56         pub fn from_eighths_of_hour(eighths_of_hour: i8) -> Box<Self> {
57             Box::new(Self(icu_time::zone::UtcOffset::from_eighths_of_hour(
58                 eighths_of_hour,
59             )))
60         }
61 
62         /// Creates an offset from a string.
63         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
64         #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_str, FnInStruct)]
65         #[diplomat::rust_link(icu::time::zone::UtcOffset::try_from_utf8, FnInStruct, hidden)]
66         #[diplomat::rust_link(icu::time::zone::UtcOffset::from_str, FnInStruct, hidden)]
67         #[diplomat::attr(auto, named_constructor = "from_string")]
68         #[diplomat::demo(default_constructor)]
from_string(offset: &DiplomatStr) -> Result<Box<Self>, TimeZoneInvalidOffsetError>69         pub fn from_string(offset: &DiplomatStr) -> Result<Box<Self>, TimeZoneInvalidOffsetError> {
70             icu_time::zone::UtcOffset::try_from_utf8(offset)
71                 .map_err(|_| TimeZoneInvalidOffsetError)
72                 .map(Self)
73                 .map(Box::new)
74         }
75 
76         /// Gets the offset as eighths of an hour.
77         #[diplomat::rust_link(icu::time::zone::UtcOffset::to_eighths_of_hour, FnInStruct)]
78         #[diplomat::attr(auto, getter)]
eighths_of_hour(&self) -> i879         pub fn eighths_of_hour(&self) -> i8 {
80             self.0.to_eighths_of_hour()
81         }
82 
83         /// Returns the value as offset seconds.
84         #[diplomat::rust_link(icu::time::TimeZoneInfo::offset, FnInStruct)]
85         #[diplomat::rust_link(icu::time::zone::UtcOffset::to_seconds, FnInStruct)]
86         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
87         #[diplomat::attr(auto, getter)]
seconds(&self) -> i3288         pub fn seconds(&self) -> i32 {
89             self.0.to_seconds()
90         }
91 
92         /// Returns whether the offset is positive.
93         #[diplomat::rust_link(icu::time::zone::UtcOffset::is_non_negative, FnInStruct)]
94         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
95         #[diplomat::attr(auto, getter)]
is_non_negative(&self) -> bool96         pub fn is_non_negative(&self) -> bool {
97             self.0.is_non_negative()
98         }
99 
100         /// Returns whether the offset is zero.
101         #[diplomat::rust_link(icu::time::zone::UtcOffset::is_zero, FnInStruct)]
102         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
103         #[diplomat::attr(auto, getter)]
is_zero(&self) -> bool104         pub fn is_zero(&self) -> bool {
105             self.0.is_zero()
106         }
107 
108         /// Returns the hours part of the offset.
109         #[diplomat::rust_link(icu::time::zone::UtcOffset::hours_part, FnInStruct)]
110         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
111         #[diplomat::attr(auto, getter)]
hours_part(&self) -> i32112         pub fn hours_part(&self) -> i32 {
113             self.0.hours_part()
114         }
115 
116         /// Returns the minutes part of the offset.
117         #[diplomat::rust_link(icu::time::zone::UtcOffset::minutes_part, FnInStruct)]
118         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
119         #[diplomat::attr(auto, getter)]
minutes_part(&self) -> u32120         pub fn minutes_part(&self) -> u32 {
121             self.0.minutes_part()
122         }
123 
124         /// Returns the seconds part of the offset.
125         #[diplomat::rust_link(icu::time::zone::UtcOffset::seconds_part, FnInStruct)]
126         #[diplomat::rust_link(icu::time::zone::UtcOffset, Struct, compact)]
127         #[diplomat::attr(auto, getter)]
seconds_part(&self) -> u32128         pub fn seconds_part(&self) -> u32 {
129             self.0.seconds_part()
130         }
131     }
132 
133     impl UtcOffsetCalculator {
134         /// Construct a new [`UtcOffsetCalculator`] instance using compiled data.
135         #[diplomat::rust_link(icu::time::zone::UtcOffsetCalculator::new, FnInStruct)]
136         #[diplomat::attr(auto, constructor)]
137         #[cfg(feature = "compiled_data")]
create() -> Box<UtcOffsetCalculator>138         pub fn create() -> Box<UtcOffsetCalculator> {
139             Box::new(UtcOffsetCalculator(
140                 icu_time::zone::UtcOffsetCalculator::new(),
141             ))
142         }
143         /// Construct a new [`UtcOffsetCalculator`] instance using a particular data source.
144         #[diplomat::rust_link(icu::time::zone::UtcOffsetCalculator::new, FnInStruct)]
145         #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")]
146         #[cfg(feature = "buffer_provider")]
create_with_provider( provider: &DataProvider, ) -> Result<Box<UtcOffsetCalculator>, DataError>147         pub fn create_with_provider(
148             provider: &DataProvider,
149         ) -> Result<Box<UtcOffsetCalculator>, DataError> {
150             Ok(Box::new(UtcOffsetCalculator(
151                 icu_time::zone::UtcOffsetCalculator::try_new_with_buffer_provider(provider.get()?)?,
152             )))
153         }
154 
155         #[diplomat::rust_link(
156             icu::time::zone::UtcOffsetCalculator::compute_offsets_from_time_zone,
157             FnInStruct
158         )]
compute_offsets_from_time_zone( &self, time_zone: &TimeZone, local_date: &IsoDate, local_time: &Time, ) -> Option<UtcOffsets>159         pub fn compute_offsets_from_time_zone(
160             &self,
161             time_zone: &TimeZone,
162             local_date: &IsoDate,
163             local_time: &Time,
164         ) -> Option<UtcOffsets> {
165             let icu_time::zone::UtcOffsets {
166                 standard, daylight, ..
167             } = self
168                 .0
169                 .compute_offsets_from_time_zone(time_zone.0, (local_date.0, local_time.0))?;
170 
171             Some(UtcOffsets {
172                 standard: Box::new(UtcOffset(standard)),
173                 daylight: daylight.map(UtcOffset).map(Box::new),
174             })
175         }
176     }
177 }
178