1#[diplomat::bridge]
6pub mod ffi {
7 use alloc::boxed::Box;
8 use alloc::sync::Arc;
9 use core::fmt::Write;
10 use icu_calendar::types::IsoWeekday;
11 use icu_calendar::AnyCalendar;
12 use icu_calendar::{Date, Iso};
13 use tinystr::TinyAsciiStr;
14
15 use crate::calendar::ffi::ICU4XCalendar;
16 use crate::errors::ffi::ICU4XError;
17
18 #[cfg(feature = "icu_calendar")]
19 use crate::week::ffi::ICU4XWeekCalculator;
20
21 #[diplomat::enum_convert(IsoWeekday)]
22 pub enum ICU4XIsoWeekday {
23 Monday = 1,
24 Tuesday,
25 Wednesday,
26 Thursday,
27 Friday,
28 Saturday,
29 Sunday,
30 }
31 #[diplomat::opaque]
32 #[diplomat::transparent_convert]
33 #[diplomat::rust_link(icu::calendar::Date, Struct)]
35 pub struct ICU4XIsoDate(pub Date<Iso>);
36
37 impl ICU4XIsoDate {
38 #[diplomat::rust_link(icu::calendar::Date::try_new_iso_date, FnInStruct)]
40 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors), constructor)]
41 pub fn create(year: i32, month: u8, day: u8) -> Result<Box<ICU4XIsoDate>, ICU4XError> {
42 Ok(Box::new(ICU4XIsoDate(Date::try_new_iso_date(
43 year, month, day,
44 )?)))
45 }
46
47 #[diplomat::rust_link(icu::calendar::Date::unix_epoch, FnInStruct)]
49 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "for_unix_epoch")]
50 pub fn create_for_unix_epoch() -> Box<ICU4XIsoDate> {
51 Box::new(ICU4XIsoDate(Date::unix_epoch()))
52 }
53
54 #[diplomat::rust_link(icu::calendar::Date::to_calendar, FnInStruct)]
56 pub fn to_calendar(&self, calendar: &ICU4XCalendar) -> Box<ICU4XDate> {
57 Box::new(ICU4XDate(self.0.to_calendar(calendar.0.clone())))
58 }
59
60 #[diplomat::rust_link(icu::calendar::Date::to_any, FnInStruct)]
61 pub fn to_any(&self) -> Box<ICU4XDate> {
62 Box::new(ICU4XDate(self.0.to_any().wrap_calendar_in_arc()))
63 }
64
65 #[diplomat::rust_link(icu::calendar::Date::day_of_year_info, FnInStruct)]
67 #[diplomat::attr(supports = accessors, getter)]
68 pub fn day_of_year(&self) -> u16 {
69 self.0.day_of_year_info().day_of_year
70 }
71
72 #[diplomat::rust_link(icu::calendar::Date::day_of_month, FnInStruct)]
74 #[diplomat::attr(supports = accessors, getter)]
75 pub fn day_of_month(&self) -> u32 {
76 self.0.day_of_month().0
77 }
78
79 #[diplomat::rust_link(icu::calendar::Date::day_of_week, FnInStruct)]
81 #[diplomat::attr(supports = accessors, getter)]
82 pub fn day_of_week(&self) -> ICU4XIsoWeekday {
83 self.0.day_of_week().into()
84 }
85
86 #[diplomat::rust_link(icu::calendar::Date::week_of_month, FnInStruct)]
91 #[diplomat::rust_link(
92 icu::calendar::week::WeekCalculator::week_of_month,
93 FnInStruct,
94 hidden
95 )]
96 pub fn week_of_month(&self, first_weekday: ICU4XIsoWeekday) -> u32 {
97 self.0.week_of_month(first_weekday.into()).0
98 }
99
100 #[diplomat::rust_link(icu::calendar::Date::week_of_year, FnInStruct)]
102 #[diplomat::rust_link(
103 icu::calendar::week::WeekCalculator::week_of_year,
104 FnInStruct,
105 hidden
106 )]
107 #[cfg(feature = "icu_calendar")]
108 pub fn week_of_year(
109 &self,
110 calculator: &ICU4XWeekCalculator,
111 ) -> Result<crate::week::ffi::ICU4XWeekOf, ICU4XError> {
112 Ok(self.0.week_of_year(&calculator.0)?.into())
113 }
114
115 #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
117 #[diplomat::attr(supports = accessors, getter)]
118 pub fn month(&self) -> u32 {
119 self.0.month().ordinal
120 }
121
122 #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct)]
124 #[diplomat::attr(supports = accessors, getter)]
125 pub fn year(&self) -> i32 {
126 self.0.year().number
127 }
128
129 #[diplomat::rust_link(icu::calendar::Date::is_in_leap_year, FnInStruct)]
131 #[diplomat::attr(supports = accessors, getter)]
132 pub fn is_in_leap_year(&self) -> bool {
133 self.0.is_in_leap_year()
134 }
135
136 #[diplomat::rust_link(icu::calendar::Date::months_in_year, FnInStruct)]
138 #[diplomat::attr(supports = accessors, getter)]
139 pub fn months_in_year(&self) -> u8 {
140 self.0.months_in_year()
141 }
142
143 #[diplomat::rust_link(icu::calendar::Date::days_in_month, FnInStruct)]
145 #[diplomat::attr(supports = accessors, getter)]
146 pub fn days_in_month(&self) -> u8 {
147 self.0.days_in_month()
148 }
149
150 #[diplomat::rust_link(icu::calendar::Date::days_in_year, FnInStruct)]
152 #[diplomat::attr(supports = accessors, getter)]
153 pub fn days_in_year(&self) -> u16 {
154 self.0.days_in_year()
155 }
156 }
157
158 #[diplomat::opaque]
159 #[diplomat::transparent_convert]
160 #[diplomat::rust_link(icu::calendar::Date, Struct)]
162 pub struct ICU4XDate(pub Date<Arc<AnyCalendar>>);
163
164 impl ICU4XDate {
165 #[diplomat::rust_link(icu::calendar::Date::new_from_iso, FnInStruct)]
168 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_iso_in_calendar")]
169 pub fn create_from_iso_in_calendar(
170 year: i32,
171 month: u8,
172 day: u8,
173 calendar: &ICU4XCalendar,
174 ) -> Result<Box<ICU4XDate>, ICU4XError> {
175 let cal = calendar.0.clone();
176 Ok(Box::new(ICU4XDate(
177 Date::try_new_iso_date(year, month, day)?.to_calendar(cal),
178 )))
179 }
180
181 #[diplomat::rust_link(icu::calendar::Date::try_new_from_codes, FnInStruct)]
183 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_codes_in_calendar")]
184 pub fn create_from_codes_in_calendar(
185 era_code: &DiplomatStr,
186 year: i32,
187 month_code: &DiplomatStr,
188 day: u8,
189 calendar: &ICU4XCalendar,
190 ) -> Result<Box<ICU4XDate>, ICU4XError> {
191 let era = TinyAsciiStr::from_bytes(era_code)
192 .map_err(|_| ICU4XError::CalendarUnknownEraError)?
193 .into();
194 let month = TinyAsciiStr::from_bytes(month_code)
195 .map_err(|_| ICU4XError::CalendarUnknownMonthCodeError)?
196 .into();
197 let cal = calendar.0.clone();
198 Ok(Box::new(ICU4XDate(Date::try_new_from_codes(
199 era, year, month, day, cal,
200 )?)))
201 }
202
203 #[diplomat::rust_link(icu::calendar::Date::to_calendar, FnInStruct)]
205 pub fn to_calendar(&self, calendar: &ICU4XCalendar) -> Box<ICU4XDate> {
206 Box::new(ICU4XDate(self.0.to_calendar(calendar.0.clone())))
207 }
208
209 #[diplomat::rust_link(icu::calendar::Date::to_iso, FnInStruct)]
211 pub fn to_iso(&self) -> Box<ICU4XIsoDate> {
212 Box::new(ICU4XIsoDate(self.0.to_iso()))
213 }
214
215 #[diplomat::rust_link(icu::calendar::Date::day_of_year_info, FnInStruct)]
217 #[diplomat::attr(supports = accessors, getter)]
218 pub fn day_of_year(&self) -> u16 {
219 self.0.day_of_year_info().day_of_year
220 }
221
222 #[diplomat::rust_link(icu::calendar::Date::day_of_month, FnInStruct)]
224 #[diplomat::attr(supports = accessors, getter)]
225 pub fn day_of_month(&self) -> u32 {
226 self.0.day_of_month().0
227 }
228
229 #[diplomat::rust_link(icu::calendar::Date::day_of_week, FnInStruct)]
231 #[diplomat::attr(supports = accessors, getter)]
232 pub fn day_of_week(&self) -> ICU4XIsoWeekday {
233 self.0.day_of_week().into()
234 }
235
236 #[diplomat::rust_link(icu::calendar::Date::week_of_month, FnInStruct)]
241 #[diplomat::rust_link(
242 icu::calendar::week::WeekCalculator::week_of_month,
243 FnInStruct,
244 hidden
245 )]
246 pub fn week_of_month(&self, first_weekday: ICU4XIsoWeekday) -> u32 {
247 self.0.week_of_month(first_weekday.into()).0
248 }
249
250 #[diplomat::rust_link(icu::calendar::Date::week_of_year, FnInStruct)]
252 #[diplomat::rust_link(
253 icu::calendar::week::WeekCalculator::week_of_year,
254 FnInStruct,
255 hidden
256 )]
257 #[cfg(feature = "icu_calendar")]
258 pub fn week_of_year(
259 &self,
260 calculator: &ICU4XWeekCalculator,
261 ) -> Result<crate::week::ffi::ICU4XWeekOf, ICU4XError> {
262 Ok(self.0.week_of_year(&calculator.0)?.into())
263 }
264
265 #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
271 #[diplomat::attr(supports = accessors, getter)]
272 pub fn ordinal_month(&self) -> u32 {
273 self.0.month().ordinal
274 }
275
276 #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
279 #[diplomat::attr(supports = accessors, getter)]
280 pub fn month_code(
281 &self,
282 write: &mut diplomat_runtime::DiplomatWriteable,
283 ) -> Result<(), ICU4XError> {
284 let code = self.0.month().code;
285 write.write_str(&code.0)?;
286 Ok(())
287 }
288
289 #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct)]
291 #[diplomat::attr(supports = accessors, getter)]
292 pub fn year_in_era(&self) -> i32 {
293 self.0.year().number
294 }
295
296 #[diplomat::rust_link(icu::Date::year, FnInStruct)]
298 #[diplomat::rust_link(icu::types::Era, Struct, compact)]
299 #[diplomat::attr(supports = accessors, getter)]
300 pub fn era(
301 &self,
302 write: &mut diplomat_runtime::DiplomatWriteable,
303 ) -> Result<(), ICU4XError> {
304 let era = self.0.year().era;
305 write.write_str(&era.0)?;
306 Ok(())
307 }
308
309 #[diplomat::rust_link(icu::calendar::Date::months_in_year, FnInStruct)]
311 #[diplomat::attr(supports = accessors, getter)]
312 pub fn months_in_year(&self) -> u8 {
313 self.0.months_in_year()
314 }
315
316 #[diplomat::rust_link(icu::calendar::Date::days_in_month, FnInStruct)]
318 #[diplomat::attr(supports = accessors, getter)]
319 pub fn days_in_month(&self) -> u8 {
320 self.0.days_in_month()
321 }
322
323 #[diplomat::rust_link(icu::calendar::Date::days_in_year, FnInStruct)]
325 #[diplomat::attr(supports = accessors, getter)]
326 pub fn days_in_year(&self) -> u16 {
327 self.0.days_in_year()
328 }
329
330 #[diplomat::rust_link(icu::calendar::Date::calendar, FnInStruct)]
332 #[diplomat::rust_link(icu::calendar::Date::calendar_wrapper, FnInStruct, hidden)]
333 #[diplomat::attr(supports = accessors, getter)]
334 pub fn calendar(&self) -> Box<ICU4XCalendar> {
335 Box::new(ICU4XCalendar(self.0.calendar_wrapper().clone()))
336 }
337 }
338}