tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

date.rs (17157B)


      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 use ffi::IsoWeekOfYear;
      6 
      7 #[diplomat::bridge]
      8 #[diplomat::abi_rename = "icu4x_{0}_mv1"]
      9 #[diplomat::attr(auto, namespace = "icu4x")]
     10 pub mod ffi {
     11    use alloc::boxed::Box;
     12    use alloc::sync::Arc;
     13    use core::fmt::Write;
     14    use icu_calendar::Iso;
     15 
     16    use crate::unstable::calendar::ffi::Calendar;
     17    use crate::unstable::errors::ffi::{CalendarError, Rfc9557ParseError};
     18 
     19    use tinystr::TinyAsciiStr;
     20 
     21    #[diplomat::enum_convert(icu_calendar::types::Weekday)]
     22    pub enum Weekday {
     23        Monday = 1,
     24        Tuesday,
     25        Wednesday,
     26        Thursday,
     27        Friday,
     28        Saturday,
     29        Sunday,
     30    }
     31    #[diplomat::opaque]
     32    #[diplomat::transparent_convert]
     33    /// An ICU4X Date object capable of containing a ISO-8601 date
     34    #[diplomat::rust_link(icu::calendar::Date, Struct)]
     35    pub struct IsoDate(pub icu_calendar::Date<icu_calendar::Iso>);
     36 
     37    impl IsoDate {
     38        /// Creates a new [`IsoDate`] from the specified date.
     39        #[diplomat::rust_link(icu::calendar::Date::try_new_iso, FnInStruct)]
     40        #[diplomat::attr(supports = fallible_constructors, constructor)]
     41        pub fn create(year: i32, month: u8, day: u8) -> Result<Box<IsoDate>, CalendarError> {
     42            Ok(Box::new(IsoDate(icu_calendar::Date::try_new_iso(
     43                year, month, day,
     44            )?)))
     45        }
     46 
     47        /// Creates a new [`IsoDate`] from the given Rata Die
     48        #[diplomat::rust_link(icu::calendar::Date::from_rata_die, FnInStruct)]
     49        #[diplomat::attr(all(supports = named_constructors), named_constructor)]
     50        #[diplomat::demo(default_constructor)]
     51        pub fn from_rata_die(rd: i64) -> Box<IsoDate> {
     52            Box::new(IsoDate(icu_calendar::Date::from_rata_die(
     53                icu_calendar::types::RataDie::new(rd),
     54                Iso,
     55            )))
     56        }
     57 
     58        /// Creates a new [`IsoDate`] from an IXDTF string.
     59        #[diplomat::rust_link(icu::calendar::Date::try_from_str, FnInStruct)]
     60        #[diplomat::rust_link(icu::calendar::Date::try_from_utf8, FnInStruct, hidden)]
     61        #[diplomat::rust_link(icu::calendar::Date::from_str, FnInStruct, hidden)]
     62        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor)]
     63        pub fn from_string(v: &DiplomatStr) -> Result<Box<IsoDate>, Rfc9557ParseError> {
     64            Ok(Box::new(IsoDate(icu_calendar::Date::try_from_utf8(
     65                v, Iso,
     66            )?)))
     67        }
     68 
     69        /// Convert this date to one in a different calendar
     70        #[diplomat::rust_link(icu::calendar::Date::to_calendar, FnInStruct)]
     71        pub fn to_calendar(&self, calendar: &Calendar) -> Box<Date> {
     72            Box::new(Date(self.0.to_calendar(calendar.0.clone())))
     73        }
     74 
     75        #[diplomat::rust_link(icu::calendar::Date::to_any, FnInStruct)]
     76        pub fn to_any(&self) -> Box<Date> {
     77            Box::new(Date(self.0.to_any().into_atomic_ref_counted()))
     78        }
     79 
     80        /// Returns this date's Rata Die
     81        #[diplomat::rust_link(icu::calendar::Date::to_rata_die, FnInStruct)]
     82        #[diplomat::attr(auto, getter = "rata_die")]
     83        pub fn to_rata_die(&self) -> i64 {
     84            self.0.to_rata_die().to_i64_date()
     85        }
     86 
     87        /// Returns the 1-indexed day in the year for this date
     88        #[diplomat::rust_link(icu::calendar::Date::day_of_year, FnInStruct)]
     89        #[diplomat::attr(auto, getter)]
     90        pub fn day_of_year(&self) -> u16 {
     91            self.0.day_of_year().0
     92        }
     93 
     94        /// Returns the 1-indexed day in the month for this date
     95        #[diplomat::rust_link(icu::calendar::Date::day_of_month, FnInStruct)]
     96        #[diplomat::attr(auto, getter)]
     97        pub fn day_of_month(&self) -> u8 {
     98            self.0.day_of_month().0
     99        }
    100 
    101        /// Returns the day in the week for this day
    102        #[diplomat::rust_link(icu::calendar::Date::day_of_week, FnInStruct)]
    103        #[diplomat::attr(auto, getter)]
    104        pub fn day_of_week(&self) -> Weekday {
    105            self.0.day_of_week().into()
    106        }
    107 
    108        /// Returns the week number in this year, using week data
    109        #[diplomat::rust_link(icu::calendar::Date::week_of_year, FnInStruct)]
    110        #[cfg(feature = "calendar")]
    111        pub fn week_of_year(&self) -> IsoWeekOfYear {
    112            self.0.week_of_year().into()
    113        }
    114 
    115        /// Returns 1-indexed number of the month of this date in its year
    116        #[diplomat::rust_link(icu::calendar::types::MonthInfo::ordinal, StructField)]
    117        #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct, compact)]
    118        #[diplomat::attr(auto, getter)]
    119        pub fn month(&self) -> u8 {
    120            self.0.month().ordinal
    121        }
    122 
    123        /// Returns the year number in the current era for this date
    124        ///
    125        /// For calendars without an era, returns the extended year
    126        #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct)]
    127        #[diplomat::attr(auto, getter)]
    128        pub fn year(&self) -> i32 {
    129            self.0.extended_year()
    130        }
    131 
    132        /// Returns if the year is a leap year for this date
    133        #[diplomat::rust_link(icu::calendar::Date::is_in_leap_year, FnInStruct)]
    134        #[diplomat::attr(auto, getter)]
    135        pub fn is_in_leap_year(&self) -> bool {
    136            self.0.is_in_leap_year()
    137        }
    138 
    139        /// Returns the number of months in the year represented by this date
    140        #[diplomat::rust_link(icu::calendar::Date::months_in_year, FnInStruct)]
    141        #[diplomat::attr(auto, getter)]
    142        pub fn months_in_year(&self) -> u8 {
    143            self.0.months_in_year()
    144        }
    145 
    146        /// Returns the number of days in the month represented by this date
    147        #[diplomat::rust_link(icu::calendar::Date::days_in_month, FnInStruct)]
    148        #[diplomat::attr(auto, getter)]
    149        pub fn days_in_month(&self) -> u8 {
    150            self.0.days_in_month()
    151        }
    152 
    153        /// Returns the number of days in the year represented by this date
    154        #[diplomat::rust_link(icu::calendar::Date::days_in_year, FnInStruct)]
    155        #[diplomat::attr(auto, getter)]
    156        pub fn days_in_year(&self) -> u16 {
    157            self.0.days_in_year()
    158        }
    159    }
    160 
    161    #[diplomat::opaque]
    162    #[diplomat::transparent_convert]
    163    /// An ICU4X Date object capable of containing a date for any calendar.
    164    #[diplomat::rust_link(icu::calendar::Date, Struct)]
    165    pub struct Date(pub icu_calendar::Date<Arc<icu_calendar::AnyCalendar>>);
    166 
    167    impl Date {
    168        /// Creates a new [`Date`] representing the ISO date
    169        /// given but in a given calendar
    170        #[diplomat::rust_link(icu::calendar::Date::new_from_iso, FnInStruct)]
    171        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor)]
    172        #[diplomat::demo(default_constructor)]
    173        pub fn from_iso_in_calendar(
    174            year: i32,
    175            month: u8,
    176            day: u8,
    177            calendar: &Calendar,
    178        ) -> Result<Box<Date>, CalendarError> {
    179            let cal = calendar.0.clone();
    180            Ok(Box::new(Date(
    181                icu_calendar::Date::try_new_iso(year, month, day)?.to_calendar(cal),
    182            )))
    183        }
    184 
    185        /// Creates a new [`Date`] from the given codes, which are interpreted in the given calendar system
    186        ///
    187        /// An empty era code will treat the year as an extended year
    188        #[diplomat::rust_link(icu::calendar::Date::try_new_from_codes, FnInStruct)]
    189        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor)]
    190        pub fn from_codes_in_calendar(
    191            era_code: &DiplomatStr,
    192            year: i32,
    193            month_code: &DiplomatStr,
    194            day: u8,
    195            calendar: &Calendar,
    196        ) -> Result<Box<Date>, CalendarError> {
    197            let era = if !era_code.is_empty() {
    198                Some(core::str::from_utf8(era_code).map_err(|_| CalendarError::UnknownEra)?)
    199            } else {
    200                None
    201            };
    202            let month = icu_calendar::types::MonthCode(
    203                TinyAsciiStr::try_from_utf8(month_code)
    204                    .map_err(|_| CalendarError::UnknownMonthCode)?,
    205            );
    206            let cal = calendar.0.clone();
    207            Ok(Box::new(Date(icu_calendar::Date::try_new_from_codes(
    208                era, year, month, day, cal,
    209            )?)))
    210        }
    211 
    212        /// Creates a new [`Date`] from the given Rata Die
    213        #[diplomat::rust_link(icu::calendar::Date::from_rata_die, FnInStruct)]
    214        #[diplomat::attr(all(supports = named_constructors), named_constructor)]
    215        #[diplomat::demo(default_constructor)]
    216        pub fn from_rata_die(rd: i64, calendar: &Calendar) -> Result<Box<Date>, CalendarError> {
    217            let cal = calendar.0.clone();
    218            Ok(Box::new(Date(icu_calendar::Date::from_rata_die(
    219                icu_calendar::types::RataDie::new(rd),
    220                cal,
    221            ))))
    222        }
    223 
    224        /// Creates a new [`Date`] from an IXDTF string.
    225        #[diplomat::rust_link(icu::calendar::Date::try_from_str, FnInStruct)]
    226        #[diplomat::rust_link(icu::calendar::Date::try_from_utf8, FnInStruct, hidden)]
    227        #[diplomat::rust_link(icu::calendar::Date::from_str, FnInStruct, hidden)]
    228        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor)]
    229        pub fn from_string(
    230            v: &DiplomatStr,
    231            calendar: &Calendar,
    232        ) -> Result<Box<Date>, Rfc9557ParseError> {
    233            Ok(Box::new(Date(icu_calendar::Date::try_from_utf8(
    234                v,
    235                calendar.0.clone(),
    236            )?)))
    237        }
    238 
    239        /// Convert this date to one in a different calendar
    240        #[diplomat::rust_link(icu::calendar::Date::to_calendar, FnInStruct)]
    241        #[diplomat::rust_link(icu::calendar::Date::convert_any, FnInStruct, hidden)]
    242        pub fn to_calendar(&self, calendar: &Calendar) -> Box<Date> {
    243            Box::new(Date(self.0.to_calendar(calendar.0.clone())))
    244        }
    245 
    246        /// Converts this date to ISO
    247        #[diplomat::rust_link(icu::calendar::Date::to_iso, FnInStruct)]
    248        pub fn to_iso(&self) -> Box<IsoDate> {
    249            Box::new(IsoDate(self.0.to_iso()))
    250        }
    251 
    252        /// Returns this date's Rata Die
    253        #[diplomat::rust_link(icu::calendar::Date::to_rata_die, FnInStruct)]
    254        #[diplomat::attr(auto, getter = "rata_die")]
    255        pub fn to_rata_die(&self) -> i64 {
    256            self.0.to_rata_die().to_i64_date()
    257        }
    258 
    259        /// Returns the 1-indexed day in the year for this date
    260        #[diplomat::rust_link(icu::calendar::Date::day_of_year, FnInStruct)]
    261        #[diplomat::attr(auto, getter)]
    262        pub fn day_of_year(&self) -> u16 {
    263            self.0.day_of_year().0
    264        }
    265 
    266        /// Returns the 1-indexed day in the month for this date
    267        #[diplomat::rust_link(icu::calendar::Date::day_of_month, FnInStruct)]
    268        #[diplomat::attr(auto, getter)]
    269        pub fn day_of_month(&self) -> u8 {
    270            self.0.day_of_month().0
    271        }
    272 
    273        /// Returns the day in the week for this day
    274        #[diplomat::rust_link(icu::calendar::Date::day_of_week, FnInStruct)]
    275        #[diplomat::attr(auto, getter)]
    276        pub fn day_of_week(&self) -> Weekday {
    277            self.0.day_of_week().into()
    278        }
    279 
    280        /// Returns 1-indexed number of the month of this date in its year
    281        ///
    282        /// Note that for lunar calendars this may not lead to the same month
    283        /// having the same ordinal month across years; use month_code if you care
    284        /// about month identity.
    285        #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct)]
    286        #[diplomat::rust_link(icu::calendar::types::MonthInfo::ordinal, StructField)]
    287        #[diplomat::attr(auto, getter)]
    288        pub fn ordinal_month(&self) -> u8 {
    289            self.0.month().ordinal
    290        }
    291 
    292        /// Returns the month code for this date. Typically something
    293        /// like "M01", "M02", but can be more complicated for lunar calendars.
    294        #[diplomat::rust_link(icu::calendar::types::MonthInfo::standard_code, StructField)]
    295        #[diplomat::rust_link(icu::calendar::Date::month, FnInStruct, compact)]
    296        #[diplomat::rust_link(icu::calendar::types::MonthInfo, Struct, hidden)]
    297        #[diplomat::rust_link(
    298            icu::calendar::types::MonthInfo::formatting_code,
    299            StructField,
    300            hidden
    301        )]
    302        #[diplomat::rust_link(icu::calendar::types::MonthInfo, Struct, hidden)]
    303        #[diplomat::attr(auto, getter)]
    304        pub fn month_code(&self, write: &mut diplomat_runtime::DiplomatWrite) {
    305            let code = self.0.month().standard_code;
    306            let _infallible = write.write_str(&code.0);
    307        }
    308 
    309        /// Returns the month number of this month.
    310        #[diplomat::rust_link(icu::calendar::types::MonthInfo::month_number, FnInStruct)]
    311        #[diplomat::attr(auto, getter)]
    312        pub fn month_number(&self) -> u8 {
    313            self.0.month().month_number()
    314        }
    315 
    316        /// Returns whether the month is a leap month.
    317        #[diplomat::rust_link(icu::calendar::types::MonthInfo::is_leap, FnInStruct)]
    318        #[diplomat::attr(auto, getter)]
    319        pub fn month_is_leap(&self) -> bool {
    320            self.0.month().is_leap()
    321        }
    322 
    323        /// Returns the year number in the current era for this date
    324        ///
    325        /// For calendars without an era, returns the related ISO year.
    326        #[diplomat::rust_link(icu::calendar::types::YearInfo::era_year_or_related_iso, FnInEnum)]
    327        #[diplomat::rust_link(icu::calendar::types::EraYear::year, StructField, compact)]
    328        #[diplomat::rust_link(icu::calendar::types::CyclicYear::related_iso, StructField, compact)]
    329        #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct, compact)]
    330        #[diplomat::rust_link(icu::calendar::Date::era_year, FnInStruct, hidden)]
    331        #[diplomat::rust_link(icu::calendar::Date::cyclic_year, FnInStruct, hidden)]
    332        #[diplomat::rust_link(icu::calendar::types::YearInfo, Enum, hidden)]
    333        #[diplomat::rust_link(icu::calendar::types::YearInfo::era, FnInEnum, hidden)]
    334        #[diplomat::rust_link(icu::calendar::types::YearInfo::cyclic, FnInEnum, hidden)]
    335        #[diplomat::rust_link(icu::calendar::types::EraYear, Struct, hidden)]
    336        #[diplomat::rust_link(icu::calendar::types::CyclicYear, Struct, hidden)]
    337        #[diplomat::attr(auto, getter)]
    338        pub fn era_year_or_related_iso(&self) -> i32 {
    339            self.0.year().era_year_or_related_iso()
    340        }
    341 
    342        /// Returns the extended year in the Date
    343        #[diplomat::rust_link(icu::calendar::Date::extended_year, FnInStruct)]
    344        #[diplomat::attr(auto, getter)]
    345        pub fn extended_year(&self) -> i32 {
    346            self.0.extended_year()
    347        }
    348 
    349        /// Returns the era for this date, or an empty string
    350        #[diplomat::rust_link(icu::calendar::types::EraYear::era, StructField)]
    351        #[diplomat::rust_link(icu::calendar::Date::year, FnInStruct, compact)]
    352        #[diplomat::attr(auto, getter)]
    353        pub fn era(&self, write: &mut diplomat_runtime::DiplomatWrite) {
    354            if let Some(era) = self.0.year().era() {
    355                let _infallible = write.write_str(&era.era);
    356            }
    357        }
    358 
    359        /// Returns the number of months in the year represented by this date
    360        #[diplomat::rust_link(icu::calendar::Date::months_in_year, FnInStruct)]
    361        #[diplomat::attr(auto, getter)]
    362        pub fn months_in_year(&self) -> u8 {
    363            self.0.months_in_year()
    364        }
    365 
    366        /// Returns the number of days in the month represented by this date
    367        #[diplomat::rust_link(icu::calendar::Date::days_in_month, FnInStruct)]
    368        #[diplomat::attr(auto, getter)]
    369        pub fn days_in_month(&self) -> u8 {
    370            self.0.days_in_month()
    371        }
    372 
    373        /// Returns the number of days in the year represented by this date
    374        #[diplomat::rust_link(icu::calendar::Date::days_in_year, FnInStruct)]
    375        #[diplomat::attr(auto, getter)]
    376        pub fn days_in_year(&self) -> u16 {
    377            self.0.days_in_year()
    378        }
    379 
    380        /// Returns the [`Calendar`] object backing this date
    381        #[diplomat::rust_link(icu::calendar::Date::calendar, FnInStruct)]
    382        #[diplomat::rust_link(icu::calendar::Date::calendar_wrapper, FnInStruct, hidden)]
    383        #[diplomat::attr(auto, getter)]
    384        pub fn calendar(&self) -> Box<Calendar> {
    385            Box::new(Calendar(self.0.calendar_wrapper().clone()))
    386        }
    387    }
    388 
    389    pub struct IsoWeekOfYear {
    390        pub week_number: u8,
    391        pub iso_year: i32,
    392    }
    393 }
    394 
    395 impl From<icu_calendar::types::IsoWeekOfYear> for IsoWeekOfYear {
    396    fn from(
    397        icu_calendar::types::IsoWeekOfYear {
    398            week_number,
    399            iso_year,
    400        }: icu_calendar::types::IsoWeekOfYear,
    401    ) -> Self {
    402        Self {
    403            week_number,
    404            iso_year,
    405        }
    406    }
    407 }