1#[diplomat::bridge]
6pub mod ffi {
7 use alloc::boxed::Box;
8 use alloc::sync::Arc;
9 use core::convert::TryInto;
10 use core::fmt::Write;
11
12 use icu_calendar::{AnyCalendar, DateTime, Iso, Time};
13 use tinystr::TinyAsciiStr;
14
15 use crate::calendar::ffi::ICU4XCalendar;
16 use crate::date::ffi::{ICU4XDate, ICU4XIsoDate, ICU4XIsoWeekday};
17 use crate::errors::ffi::ICU4XError;
18 use crate::time::ffi::ICU4XTime;
19
20 #[cfg(feature = "icu_calendar")]
21 use crate::week::ffi::ICU4XWeekCalculator;
22
23 #[diplomat::opaque]
24 #[diplomat::rust_link(icu::calendar::DateTime, Struct)]
26 pub struct ICU4XIsoDateTime(pub DateTime<Iso>);
27
28 impl ICU4XIsoDateTime {
29 #[diplomat::rust_link(icu::calendar::DateTime::try_new_iso_datetime, FnInStruct)]
31 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors), constructor)]
32 pub fn create(
33 year: i32,
34 month: u8,
35 day: u8,
36 hour: u8,
37 minute: u8,
38 second: u8,
39 nanosecond: u32,
40 ) -> Result<Box<ICU4XIsoDateTime>, ICU4XError> {
41 let mut dt = DateTime::try_new_iso_datetime(year, month, day, hour, minute, second)?;
42 dt.time.nanosecond = nanosecond.try_into()?;
43 Ok(Box::new(ICU4XIsoDateTime(dt)))
44 }
45
46 #[diplomat::rust_link(icu::calendar::DateTime::new, FnInStruct)]
48 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_date_and_time")]
49 pub fn crate_from_date_and_time(
50 date: &ICU4XIsoDate,
51 time: &ICU4XTime,
52 ) -> Box<ICU4XIsoDateTime> {
53 let dt = DateTime::new(date.0, time.0);
54 Box::new(ICU4XIsoDateTime(dt))
55 }
56
57 #[diplomat::rust_link(icu::calendar::DateTime::local_unix_epoch, FnInStruct)]
59 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "local_unix_epoch")]
60 pub fn local_unix_epoch() -> Box<ICU4XIsoDateTime> {
61 let dt = DateTime::local_unix_epoch();
62 Box::new(ICU4XIsoDateTime(dt))
63 }
64
65 #[diplomat::rust_link(
67 icu::calendar::DateTime::from_minutes_since_local_unix_epoch,
68 FnInStruct
69 )]
70 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_minutes_since_local_unix_epoch")]
71 pub fn create_from_minutes_since_local_unix_epoch(minutes: i32) -> Box<ICU4XIsoDateTime> {
72 Box::new(ICU4XIsoDateTime(
73 DateTime::from_minutes_since_local_unix_epoch(minutes),
74 ))
75 }
76
77 #[diplomat::rust_link(icu::calendar::DateTime::date, StructField)]
79 #[diplomat::attr(supports = accessors, getter)]
80 pub fn date(&self) -> Box<ICU4XIsoDate> {
81 Box::new(ICU4XIsoDate(self.0.date))
82 }
83
84 #[diplomat::rust_link(icu::calendar::DateTime::time, StructField)]
86 #[diplomat::attr(supports = accessors, getter)]
87 pub fn time(&self) -> Box<ICU4XTime> {
88 Box::new(ICU4XTime(self.0.time))
89 }
90
91 #[diplomat::rust_link(icu::calendar::DateTime::to_any, FnInStruct)]
94 #[diplomat::rust_link(icu::calendar::DateTime::new_from_iso, FnInStruct, hidden)]
95 pub fn to_any(&self) -> Box<ICU4XDateTime> {
96 Box::new(ICU4XDateTime(self.0.to_any().wrap_calendar_in_arc()))
97 }
98
99 #[diplomat::rust_link(icu::calendar::DateTime::minutes_since_local_unix_epoch, FnInStruct)]
101 #[diplomat::attr(supports = accessors, getter)]
102 pub fn minutes_since_local_unix_epoch(&self) -> i32 {
103 self.0.minutes_since_local_unix_epoch()
104 }
105
106 #[diplomat::rust_link(icu::calendar::DateTime::to_calendar, FnInStruct)]
108 pub fn to_calendar(&self, calendar: &ICU4XCalendar) -> Box<ICU4XDateTime> {
109 Box::new(ICU4XDateTime(self.0.to_calendar(calendar.0.clone())))
110 }
111
112 #[diplomat::rust_link(icu::calendar::Time::hour, StructField)]
114 #[diplomat::attr(supports = accessors, getter)]
115 pub fn hour(&self) -> u8 {
116 self.0.time.hour.into()
117 }
118 #[diplomat::rust_link(icu::calendar::Time::minute, StructField)]
120 #[diplomat::attr(supports = accessors, getter)]
121 pub fn minute(&self) -> u8 {
122 self.0.time.minute.into()
123 }
124 #[diplomat::rust_link(icu::calendar::Time::second, StructField)]
126 #[diplomat::attr(supports = accessors, getter)]
127 pub fn second(&self) -> u8 {
128 self.0.time.second.into()
129 }
130 #[diplomat::rust_link(icu::calendar::Time::nanosecond, StructField)]
132 #[diplomat::attr(supports = accessors, getter)]
133 pub fn nanosecond(&self) -> u32 {
134 self.0.time.nanosecond.into()
135 }
136
137 #[diplomat::rust_link(icu::calendar::Date::day_of_year_info, FnInStruct)]
139 #[diplomat::attr(supports = accessors, getter)]
140 pub fn day_of_year(&self) -> u16 {
141 self.0.date.day_of_year_info().day_of_year
142 }
143
144 #[diplomat::rust_link(icu::calendar::Date::day_of_month, FnInStruct)]
146 #[diplomat::attr(supports = accessors, getter)]
147 pub fn day_of_month(&self) -> u32 {
148 self.0.date.day_of_month().0
149 }
150
151 #[diplomat::rust_link(icu::calendar::Date::day_of_week, FnInStruct)]
153 #[diplomat::attr(supports = accessors, getter)]
154 pub fn day_of_week(&self) -> ICU4XIsoWeekday {
155 self.0.date.day_of_week().into()
156 }
157
158 #[diplomat::rust_link(icu::calendar::Date::week_of_month, FnInStruct)]
163 #[diplomat::rust_link(
164 icu::calendar::week::WeekCalculator::week_of_month,
165 FnInStruct,
166 hidden
167 )]
168 pub fn week_of_month(&self, first_weekday: ICU4XIsoWeekday) -> u32 {
169 self.0.date.week_of_month(first_weekday.into()).0
170 }
171
172 #[diplomat::rust_link(icu::calendar::Date::week_of_year, FnInStruct)]
174 #[diplomat::rust_link(
175 icu::calendar::week::WeekCalculator::week_of_year,
176 FnInStruct,
177 hidden
178 )]
179 #[cfg(feature = "icu_calendar")]
180 pub fn week_of_year(
181 &self,
182 calculator: &ICU4XWeekCalculator,
183 ) -> Result<crate::week::ffi::ICU4XWeekOf, ICU4XError> {
184 Ok(self.0.date.week_of_year(&calculator.0)?.into())
185 }
186
187 #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
189 #[diplomat::attr(supports = accessors, getter)]
190 pub fn month(&self) -> u32 {
191 self.0.date.month().ordinal
192 }
193
194 #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct)]
196 #[diplomat::attr(supports = accessors, getter)]
197 pub fn year(&self) -> i32 {
198 self.0.date.year().number
199 }
200
201 #[diplomat::rust_link(icu::calendar::Date::is_in_leap_year, FnInStruct)]
203 #[diplomat::attr(supports = accessors, getter)]
204 pub fn is_in_leap_year(&self) -> bool {
205 self.0.date.is_in_leap_year()
206 }
207
208 #[diplomat::rust_link(icu::calendar::Date::months_in_year, FnInStruct)]
210 #[diplomat::attr(supports = accessors, getter)]
211 pub fn months_in_year(&self) -> u8 {
212 self.0.date.months_in_year()
213 }
214
215 #[diplomat::rust_link(icu::calendar::Date::days_in_month, FnInStruct)]
217 #[diplomat::attr(supports = accessors, getter)]
218 pub fn days_in_month(&self) -> u8 {
219 self.0.date.days_in_month()
220 }
221
222 #[diplomat::rust_link(icu::calendar::Date::days_in_year, FnInStruct)]
224 #[diplomat::attr(supports = accessors, getter)]
225 pub fn days_in_year(&self) -> u16 {
226 self.0.date.days_in_year()
227 }
228 }
229
230 #[diplomat::opaque]
231 #[diplomat::rust_link(icu::calendar::DateTime, Struct)]
233 pub struct ICU4XDateTime(pub DateTime<Arc<AnyCalendar>>);
234
235 impl ICU4XDateTime {
236 #[diplomat::rust_link(icu::DateTime::new_from_iso, FnInStruct)]
239 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_iso_in_calendar")]
240 #[allow(clippy::too_many_arguments)]
241 pub fn create_from_iso_in_calendar(
242 year: i32,
243 month: u8,
244 day: u8,
245 hour: u8,
246 minute: u8,
247 second: u8,
248 nanosecond: u32,
249 calendar: &ICU4XCalendar,
250 ) -> Result<Box<ICU4XDateTime>, ICU4XError> {
251 let cal = calendar.0.clone();
252 let mut dt = DateTime::try_new_iso_datetime(year, month, day, hour, minute, second)?;
253 dt.time.nanosecond = nanosecond.try_into()?;
254 Ok(Box::new(ICU4XDateTime(dt.to_calendar(cal))))
255 }
256 #[diplomat::rust_link(icu::calendar::DateTime::try_new_from_codes, FnInStruct)]
258 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_codes_in_calendar")]
259 #[allow(clippy::too_many_arguments)]
260 pub fn create_from_codes_in_calendar(
261 era_code: &DiplomatStr,
262 year: i32,
263 month_code: &DiplomatStr,
264 day: u8,
265 hour: u8,
266 minute: u8,
267 second: u8,
268 nanosecond: u32,
269 calendar: &ICU4XCalendar,
270 ) -> Result<Box<ICU4XDateTime>, ICU4XError> {
271 let era = TinyAsciiStr::from_bytes(era_code)
272 .map_err(|_| ICU4XError::CalendarUnknownEraError)?
273 .into();
274 let month = TinyAsciiStr::from_bytes(month_code)
275 .map_err(|_| ICU4XError::CalendarUnknownMonthCodeError)?
276 .into();
277 let cal = calendar.0.clone();
278 let hour = hour.try_into()?;
279 let minute = minute.try_into()?;
280 let second = second.try_into()?;
281 let nanosecond = nanosecond.try_into()?;
282 let time = Time {
283 hour,
284 minute,
285 second,
286 nanosecond,
287 };
288 Ok(Box::new(ICU4XDateTime(DateTime::try_new_from_codes(
289 era, year, month, day, time, cal,
290 )?)))
291 }
292 #[diplomat::rust_link(icu::calendar::DateTime::new, FnInStruct)]
294 #[diplomat::attr(all(supports = constructors, supports = fallible_constructors, supports = named_constructors), named_constructor = "from_date_and_time")]
295 pub fn create_from_date_and_time(date: &ICU4XDate, time: &ICU4XTime) -> Box<ICU4XDateTime> {
296 let dt = DateTime::new(date.0.clone(), time.0);
297 Box::new(ICU4XDateTime(dt))
298 }
299
300 #[diplomat::rust_link(icu::calendar::DateTime::date, StructField)]
302 #[diplomat::attr(supports = accessors, getter)]
303 pub fn date(&self) -> Box<ICU4XDate> {
304 Box::new(ICU4XDate(self.0.date.clone()))
305 }
306
307 #[diplomat::rust_link(icu::calendar::DateTime::time, StructField)]
309 #[diplomat::attr(supports = accessors, getter)]
310 pub fn time(&self) -> Box<ICU4XTime> {
311 Box::new(ICU4XTime(self.0.time))
312 }
313
314 #[diplomat::rust_link(icu::calendar::DateTime::to_iso, FnInStruct)]
316 pub fn to_iso(&self) -> Box<ICU4XIsoDateTime> {
317 Box::new(ICU4XIsoDateTime(self.0.to_iso()))
318 }
319
320 #[diplomat::rust_link(icu::calendar::DateTime::to_calendar, FnInStruct)]
322 pub fn to_calendar(&self, calendar: &ICU4XCalendar) -> Box<ICU4XDateTime> {
323 Box::new(ICU4XDateTime(self.0.to_calendar(calendar.0.clone())))
324 }
325
326 #[diplomat::rust_link(icu::calendar::Time::hour, StructField)]
328 #[diplomat::attr(supports = accessors, getter)]
329 pub fn hour(&self) -> u8 {
330 self.0.time.hour.into()
331 }
332 #[diplomat::rust_link(icu::calendar::Time::minute, StructField)]
334 #[diplomat::attr(supports = accessors, getter)]
335 pub fn minute(&self) -> u8 {
336 self.0.time.minute.into()
337 }
338 #[diplomat::rust_link(icu::calendar::Time::second, StructField)]
340 #[diplomat::attr(supports = accessors, getter)]
341 pub fn second(&self) -> u8 {
342 self.0.time.second.into()
343 }
344 #[diplomat::rust_link(icu::calendar::Time::nanosecond, StructField)]
346 #[diplomat::attr(supports = accessors, getter)]
347 pub fn nanosecond(&self) -> u32 {
348 self.0.time.nanosecond.into()
349 }
350
351 #[diplomat::rust_link(icu::calendar::Date::day_of_year_info, FnInStruct)]
353 #[diplomat::attr(supports = accessors, getter)]
354 pub fn day_of_year(&self) -> u16 {
355 self.0.date.day_of_year_info().day_of_year
356 }
357
358 #[diplomat::rust_link(icu::calendar::Date::day_of_month, FnInStruct)]
360 #[diplomat::attr(supports = accessors, getter)]
361 pub fn day_of_month(&self) -> u32 {
362 self.0.date.day_of_month().0
363 }
364
365 #[diplomat::rust_link(icu::calendar::Date::day_of_week, FnInStruct)]
367 #[diplomat::attr(supports = accessors, getter)]
368 pub fn day_of_week(&self) -> ICU4XIsoWeekday {
369 self.0.date.day_of_week().into()
370 }
371
372 #[diplomat::rust_link(icu::calendar::Date::week_of_month, FnInStruct)]
377 #[diplomat::rust_link(
378 icu::calendar::week::WeekCalculator::week_of_month,
379 FnInStruct,
380 hidden
381 )]
382 pub fn week_of_month(&self, first_weekday: ICU4XIsoWeekday) -> u32 {
383 self.0.date.week_of_month(first_weekday.into()).0
384 }
385
386 #[diplomat::rust_link(icu::calendar::Date::week_of_year, FnInStruct)]
388 #[diplomat::rust_link(
389 icu::calendar::week::WeekCalculator::week_of_year,
390 FnInStruct,
391 hidden
392 )]
393 #[cfg(feature = "icu_calendar")]
394 pub fn week_of_year(
395 &self,
396 calculator: &ICU4XWeekCalculator,
397 ) -> Result<crate::week::ffi::ICU4XWeekOf, ICU4XError> {
398 Ok(self.0.date.week_of_year(&calculator.0)?.into())
399 }
400
401 #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
407 #[diplomat::attr(supports = accessors, getter)]
408 pub fn ordinal_month(&self) -> u32 {
409 self.0.date.month().ordinal
410 }
411
412 #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
415 #[diplomat::attr(supports = accessors, getter)]
416 pub fn month_code(
417 &self,
418 write: &mut diplomat_runtime::DiplomatWriteable,
419 ) -> Result<(), ICU4XError> {
420 let code = self.0.date.month().code;
421 write.write_str(&code.0)?;
422 Ok(())
423 }
424
425 #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct)]
427 #[diplomat::attr(supports = accessors, getter)]
428 pub fn year_in_era(&self) -> i32 {
429 self.0.date.year().number
430 }
431
432 #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct)]
434 #[diplomat::attr(supports = accessors, getter)]
435 pub fn era(
436 &self,
437 write: &mut diplomat_runtime::DiplomatWriteable,
438 ) -> Result<(), ICU4XError> {
439 let era = self.0.date.year().era;
440 write.write_str(&era.0)?;
441 Ok(())
442 }
443
444 #[diplomat::rust_link(icu::calendar::Date::months_in_year, FnInStruct)]
446 #[diplomat::attr(supports = accessors, getter)]
447 pub fn months_in_year(&self) -> u8 {
448 self.0.date.months_in_year()
449 }
450
451 #[diplomat::rust_link(icu::calendar::Date::days_in_month, FnInStruct)]
453 #[diplomat::attr(supports = accessors, getter)]
454 pub fn days_in_month(&self) -> u8 {
455 self.0.date.days_in_month()
456 }
457
458 #[diplomat::rust_link(icu::calendar::Date::days_in_year, FnInStruct)]
460 #[diplomat::attr(supports = accessors, getter)]
461 pub fn days_in_year(&self) -> u16 {
462 self.0.date.days_in_year()
463 }
464
465 #[diplomat::rust_link(icu::calendar::Date::calendar, FnInStruct)]
467 #[diplomat::rust_link(icu::calendar::Date::calendar_wrapper, FnInStruct, hidden)]
468 #[diplomat::attr(supports = accessors, getter)]
469 pub fn calendar(&self) -> Box<ICU4XCalendar> {
470 Box::new(ICU4XCalendar(self.0.date.calendar_wrapper().clone()))
471 }
472 }
473}