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 use diplomat_runtime::DiplomatStr; 11 12 use crate::timezone::ffi::TimeZone; 13 #[cfg(feature = "buffer_provider")] 14 use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; 15 16 /// A mapper between IANA time zone identifiers and BCP-47 time zone identifiers. 17 /// 18 /// This mapper supports two-way mapping, but it is optimized for the case of IANA to BCP-47. 19 /// It also supports normalizing and canonicalizing the IANA strings. 20 #[diplomat::opaque] 21 #[diplomat::rust_link(icu::time::zone::iana::IanaParser, Struct)] 22 #[diplomat::rust_link(icu::time::zone::iana::IanaParser::as_borrowed, FnInStruct, hidden)] 23 #[diplomat::rust_link(icu::time::zone::iana::IanaParserBorrowed, Struct, hidden)] 24 #[diplomat::rust_link(icu::time::zone::iana::IanaParserBorrowed::new, FnInStruct, hidden)] 25 pub struct IanaParser(pub icu_time::zone::iana::IanaParser); 26 27 impl IanaParser { 28 /// Create a new [`IanaParser`] using compiled data 29 #[diplomat::rust_link(icu::time::zone::iana::IanaParser::new, FnInStruct)] 30 #[diplomat::attr(auto, constructor)] 31 #[cfg(feature = "compiled_data")] create() -> Box<IanaParser>32 pub fn create() -> Box<IanaParser> { 33 Box::new(IanaParser( 34 icu_time::zone::iana::IanaParser::new().static_to_owned(), 35 )) 36 } 37 38 /// Create a new [`IanaParser`] using a particular data source 39 #[diplomat::rust_link(icu::time::zone::iana::IanaParser::new, FnInStruct)] 40 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")] 41 #[cfg(feature = "buffer_provider")] create_with_provider(provider: &DataProvider) -> Result<Box<IanaParser>, DataError>42 pub fn create_with_provider(provider: &DataProvider) -> Result<Box<IanaParser>, DataError> { 43 Ok(Box::new(IanaParser( 44 icu_time::zone::iana::IanaParser::try_new_with_buffer_provider(provider.get()?)?, 45 ))) 46 } 47 48 #[diplomat::rust_link(icu::time::zone::iana::IanaParserBorrowed::parse, FnInStruct)] 49 #[diplomat::rust_link( 50 icu::time::zone::iana::IanaParserBorrowed::parse_from_utf8, 51 FnInStruct, 52 hidden 53 )] parse(&self, value: &DiplomatStr) -> Box<TimeZone>54 pub fn parse(&self, value: &DiplomatStr) -> Box<TimeZone> { 55 Box::new(TimeZone(self.0.as_borrowed().parse_from_utf8(value))) 56 } 57 58 #[diplomat::rust_link(icu::time::zone::iana::IanaParserBorrowed::iter, FnInStruct)] iter<'a>(&'a self) -> Box<TimeZoneIterator<'a>>59 pub fn iter<'a>(&'a self) -> Box<TimeZoneIterator<'a>> { 60 Box::new(TimeZoneIterator(self.0.as_borrowed().iter())) 61 } 62 } 63 64 #[diplomat::opaque] 65 #[diplomat::rust_link(icu::time::zone::iana::TimeZoneIter, Struct)] 66 pub struct TimeZoneIterator<'a>(icu_time::zone::iana::TimeZoneIter<'a>); 67 68 impl<'a> TimeZoneIterator<'a> { 69 #[diplomat::attr(auto, iterator)] 70 #[diplomat::rust_link(icu::time::zone::iana::TimeZoneIter::next, FnInStruct)] next(&mut self) -> Option<Box<TimeZone>>71 pub fn next(&mut self) -> Option<Box<TimeZone>> { 72 Some(Box::new(TimeZone(self.0.next()?))) 73 } 74 } 75 76 /// A mapper between IANA time zone identifiers and BCP-47 time zone identifiers. 77 /// 78 /// This mapper supports two-way mapping, but it is optimized for the case of IANA to BCP-47. 79 /// It also supports normalizing and canonicalizing the IANA strings. 80 #[diplomat::opaque] 81 #[diplomat::rust_link(icu::time::zone::iana::IanaParserExtended, Struct)] 82 #[diplomat::rust_link( 83 icu::time::zone::iana::IanaParserExtended::as_borrowed, 84 FnInStruct, 85 hidden 86 )] 87 #[diplomat::rust_link(icu::time::zone::iana::IanaParserExtendedBorrowed, Struct, hidden)] 88 #[diplomat::rust_link( 89 icu::time::zone::iana::IanaParserExtendedBorrowed::new, 90 FnInStruct, 91 hidden 92 )] 93 pub struct IanaParserExtended( 94 pub icu_time::zone::iana::IanaParserExtended<icu_time::zone::iana::IanaParser>, 95 ); 96 97 impl IanaParserExtended { 98 /// Create a new [`IanaParserExtended`] using compiled data 99 #[diplomat::rust_link(icu::time::zone::iana::IanaParserExtended::new, FnInStruct)] 100 #[diplomat::rust_link( 101 icu::time::zone::iana::IanaParserExtended::try_new_with_parser, 102 FnInStruct, 103 hidden 104 )] 105 #[diplomat::attr(auto, constructor)] 106 #[cfg(feature = "compiled_data")] create() -> Box<IanaParserExtended>107 pub fn create() -> Box<IanaParserExtended> { 108 Box::new(IanaParserExtended( 109 icu_time::zone::iana::IanaParserExtended::new().static_to_owned(), 110 )) 111 } 112 113 /// Create a new [`IanaParserExtended`] using a particular data source 114 #[diplomat::rust_link(icu::time::zone::iana::IanaParserExtended::new, FnInStruct)] 115 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")] 116 #[cfg(feature = "buffer_provider")] create_with_provider( provider: &DataProvider, ) -> Result<Box<IanaParserExtended>, DataError>117 pub fn create_with_provider( 118 provider: &DataProvider, 119 ) -> Result<Box<IanaParserExtended>, DataError> { 120 Ok(Box::new(IanaParserExtended( 121 icu_time::zone::iana::IanaParserExtended::try_new_with_buffer_provider( 122 provider.get()?, 123 )?, 124 ))) 125 } 126 127 #[diplomat::rust_link(icu::time::zone::iana::IanaParserExtendedBorrowed::parse, FnInStruct)] 128 #[diplomat::rust_link( 129 icu::time::zone::iana::IanaParserExtendedBorrowed::parse_from_utf8, 130 FnInStruct, 131 hidden 132 )] parse<'a>(&'a self, value: &DiplomatStr) -> TimeZoneAndCanonicalAndNormalized<'a>133 pub fn parse<'a>(&'a self, value: &DiplomatStr) -> TimeZoneAndCanonicalAndNormalized<'a> { 134 let (time_zone_id, canonical, normalized) = self.0.as_borrowed().parse_from_utf8(value); 135 TimeZoneAndCanonicalAndNormalized { 136 time_zone: Box::new(TimeZone(time_zone_id)), 137 canonical: canonical.into(), 138 normalized: normalized.into(), 139 } 140 } 141 142 #[diplomat::rust_link(icu::time::zone::iana::IanaParserExtendedBorrowed::iter, FnInStruct)] iter<'a>(&'a self) -> Box<TimeZoneAndCanonicalIterator<'a>>143 pub fn iter<'a>(&'a self) -> Box<TimeZoneAndCanonicalIterator<'a>> { 144 Box::new(TimeZoneAndCanonicalIterator(self.0.as_borrowed().iter())) 145 } 146 147 #[diplomat::rust_link( 148 icu::time::zone::iana::IanaParserExtendedBorrowed::iter_all, 149 FnInStruct 150 )] iter_all<'a>(&'a self) -> Box<TimeZoneAndCanonicalAndNormalizedIterator<'a>>151 pub fn iter_all<'a>(&'a self) -> Box<TimeZoneAndCanonicalAndNormalizedIterator<'a>> { 152 Box::new(TimeZoneAndCanonicalAndNormalizedIterator( 153 self.0.as_borrowed().iter_all(), 154 )) 155 } 156 } 157 158 #[diplomat::out] 159 pub struct TimeZoneAndCanonical<'a> { 160 time_zone: Box<TimeZone>, 161 canonical: DiplomatUtf8StrSlice<'a>, 162 } 163 164 #[diplomat::opaque] 165 #[diplomat::rust_link(icu::time::zone::iana::TimeZoneAndCanonicalIter, Struct)] 166 pub struct TimeZoneAndCanonicalIterator<'a>(icu_time::zone::iana::TimeZoneAndCanonicalIter<'a>); 167 168 impl<'a> TimeZoneAndCanonicalIterator<'a> { 169 #[diplomat::attr(auto, iterator)] 170 #[diplomat::rust_link(icu::time::zone::iana::TimeZoneAndCanonicalIter::next, FnInStruct)] next(&mut self) -> Option<TimeZoneAndCanonical<'a>>171 pub fn next(&mut self) -> Option<TimeZoneAndCanonical<'a>> { 172 let (time_zone_id, canonical) = self.0.next()?; 173 Some(TimeZoneAndCanonical { 174 time_zone: Box::new(TimeZone(time_zone_id)), 175 canonical: canonical.into(), 176 }) 177 } 178 } 179 180 #[diplomat::out] 181 pub struct TimeZoneAndCanonicalAndNormalized<'a> { 182 time_zone: Box<TimeZone>, 183 canonical: DiplomatUtf8StrSlice<'a>, 184 normalized: DiplomatUtf8StrSlice<'a>, 185 } 186 187 #[diplomat::opaque] 188 #[diplomat::rust_link(icu::time::zone::iana::TimeZoneAndCanonicalAndNormalizedIter, Struct)] 189 pub struct TimeZoneAndCanonicalAndNormalizedIterator<'a>( 190 icu_time::zone::iana::TimeZoneAndCanonicalAndNormalizedIter<'a>, 191 ); 192 193 impl<'a> TimeZoneAndCanonicalAndNormalizedIterator<'a> { 194 #[diplomat::attr(auto, iterator)] 195 #[diplomat::rust_link( 196 icu::time::zone::iana::TimeZoneAndCanonicalAndNormalizedIter::next, 197 FnInStruct 198 )] next(&mut self) -> Option<TimeZoneAndCanonicalAndNormalized<'a>>199 pub fn next(&mut self) -> Option<TimeZoneAndCanonicalAndNormalized<'a>> { 200 let (time_zone_id, canonical, normalized) = self.0.next()?; 201 Some(TimeZoneAndCanonicalAndNormalized { 202 time_zone: Box::new(TimeZone(time_zone_id)), 203 canonical: canonical.into(), 204 normalized: normalized.into(), 205 }) 206 } 207 } 208 } 209