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 use crate::locale_core::ffi::Locale; 12 #[cfg(feature = "buffer_provider")] 13 use crate::{errors::ffi::DataError, provider::ffi::DataProvider}; 14 15 /// An object that runs the ICU4X locale fallback algorithm. 16 #[diplomat::opaque] 17 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbacker, Struct)] 18 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbackerBorrowed, Struct, hidden)] 19 pub struct LocaleFallbacker(pub icu_locale::LocaleFallbacker); 20 21 /// Priority mode for the ICU4X fallback algorithm. 22 #[diplomat::enum_convert(icu_locale::fallback::LocaleFallbackPriority, needs_wildcard)] 23 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbackPriority, Enum)] 24 #[diplomat::rust_link( 25 icu::locale::fallback::LocaleFallbackPriority::default, 26 FnInEnum, 27 hidden 28 )] 29 pub enum LocaleFallbackPriority { 30 Language = 0, 31 Region = 1, 32 } 33 34 /// Collection of configurations for the ICU4X fallback algorithm. 35 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbackConfig, Struct)] 36 #[diplomat::rust_link( 37 icu::locale::fallback::LocaleFallbackConfig::default, 38 FnInStruct, 39 hidden 40 )] 41 pub struct LocaleFallbackConfig { 42 /// Choice of priority mode. 43 pub priority: LocaleFallbackPriority, 44 } 45 46 /// An object that runs the ICU4X locale fallback algorithm with specific configurations. 47 #[diplomat::opaque] 48 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbacker, Struct)] 49 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbackerWithConfig, Struct)] 50 pub struct LocaleFallbackerWithConfig<'a>( 51 pub icu_locale::fallback::LocaleFallbackerWithConfig<'a>, 52 ); 53 54 /// An iterator over the locale under fallback. 55 #[diplomat::opaque] 56 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbackIterator, Struct)] 57 pub struct LocaleFallbackIterator<'a>(pub icu_locale::fallback::LocaleFallbackIterator<'a>); 58 59 impl LocaleFallbacker { 60 /// Creates a new `LocaleFallbacker` from compiled data. 61 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbacker::new, FnInStruct)] 62 #[diplomat::rust_link( 63 icu::locale::fallback::LocaleFallbackerBorrowed::new, 64 FnInStruct, 65 hidden 66 )] 67 #[diplomat::attr(auto, constructor)] 68 #[cfg(feature = "compiled_data")] create() -> Box<LocaleFallbacker>69 pub fn create() -> Box<LocaleFallbacker> { 70 Box::new(LocaleFallbacker( 71 icu_locale::LocaleFallbacker::new().static_to_owned(), 72 )) 73 } 74 75 /// Creates a new `LocaleFallbacker` from a data provider. 76 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbacker::new, FnInStruct)] 77 #[diplomat::rust_link( 78 icu::locale::fallback::LocaleFallbackerBorrowed::new, 79 FnInStruct, 80 hidden 81 )] 82 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "with_provider")] 83 #[cfg(feature = "buffer_provider")] create_with_provider( provider: &DataProvider, ) -> Result<Box<LocaleFallbacker>, DataError>84 pub fn create_with_provider( 85 provider: &DataProvider, 86 ) -> Result<Box<LocaleFallbacker>, DataError> { 87 Ok(Box::new(LocaleFallbacker( 88 icu_locale::LocaleFallbacker::try_new_with_buffer_provider(provider.get()?)?, 89 ))) 90 } 91 92 /// Creates a new `LocaleFallbacker` without data for limited functionality. 93 #[diplomat::rust_link( 94 icu::locale::fallback::LocaleFallbacker::new_without_data, 95 FnInStruct 96 )] 97 #[diplomat::attr(auto, named_constructor)] without_data() -> Box<LocaleFallbacker>98 pub fn without_data() -> Box<LocaleFallbacker> { 99 Box::new(LocaleFallbacker( 100 icu_locale::LocaleFallbacker::new_without_data(), 101 )) 102 } 103 104 /// Associates this `LocaleFallbacker` with configuration options. 105 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbacker::for_config, FnInStruct)] 106 #[diplomat::rust_link( 107 icu::locale::fallback::LocaleFallbackerBorrowed::for_config, 108 FnInStruct, 109 hidden 110 )] for_config<'a>( &'a self, config: LocaleFallbackConfig, ) -> Box<LocaleFallbackerWithConfig<'a>>111 pub fn for_config<'a>( 112 &'a self, 113 config: LocaleFallbackConfig, 114 ) -> Box<LocaleFallbackerWithConfig<'a>> { 115 Box::new(LocaleFallbackerWithConfig(self.0.for_config({ 116 let mut c = icu_locale::fallback::LocaleFallbackConfig::default(); 117 c.priority = config.priority.into(); 118 c 119 }))) 120 } 121 } 122 123 impl<'a> LocaleFallbackerWithConfig<'a> { 124 /// Creates an iterator from a locale with each step of fallback. 125 #[diplomat::rust_link(icu::locale::fallback::LocaleFallbacker::fallback_for, FnInStruct)] 126 #[diplomat::rust_link( 127 icu::locale::fallback::LocaleFallbackerBorrowed::fallback_for, 128 FnInStruct, 129 hidden 130 )] 131 #[diplomat::rust_link( 132 icu::locale::fallback::LocaleFallbackerWithConfig::fallback_for, 133 FnInStruct, 134 hidden 135 )] fallback_for_locale<'b: 'a, 'temp>( &'b self, locale: &'temp Locale, ) -> Box<LocaleFallbackIterator<'a>>136 pub fn fallback_for_locale<'b: 'a, 'temp>( 137 &'b self, 138 locale: &'temp Locale, 139 ) -> Box<LocaleFallbackIterator<'a>> { 140 Box::new(LocaleFallbackIterator( 141 self.0.fallback_for((&locale.0).into()), 142 )) 143 } 144 } 145 146 impl<'a> LocaleFallbackIterator<'a> { 147 #[diplomat::attr(auto, iterator)] 148 #[diplomat::rust_link( 149 icu::locale::fallback::LocaleFallbackIterator::get, 150 FnInStruct, 151 hidden 152 )] 153 #[diplomat::rust_link( 154 icu::locale::fallback::LocaleFallbackIterator::step, 155 FnInStruct, 156 hidden 157 )] 158 #[diplomat::rust_link( 159 icu::locale::fallback::LocaleFallbackIterator::take, 160 FnInStruct, 161 hidden 162 )] next(&mut self) -> Option<Box<Locale>>163 pub fn next(&mut self) -> Option<Box<Locale>> { 164 let current = self.0.get(); 165 if current.is_default() { 166 None 167 } else { 168 let current = *current; 169 self.0.step(); 170 Some(Box::new(Locale(current.into_locale()))) 171 } 172 } 173 } 174 } 175