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 #[cfg(any(feature = "compiled_data", feature = "buffer_provider"))] 12 use crate::errors::ffi::DataError; 13 use crate::errors::ffi::LocaleParseError; 14 use crate::locale_core::ffi::Locale; 15 #[cfg(feature = "buffer_provider")] 16 use crate::provider::ffi::DataProvider; 17 use diplomat_runtime::DiplomatOption; 18 19 use writeable::Writeable; 20 21 #[diplomat::opaque] 22 #[diplomat::rust_link(icu::displaynames::LocaleDisplayNamesFormatter, Struct)] 23 pub struct LocaleDisplayNamesFormatter( 24 pub icu_experimental::displaynames::LocaleDisplayNamesFormatter, 25 ); 26 27 #[diplomat::opaque] 28 #[diplomat::rust_link(icu::displaynames::RegionDisplayNames, Struct)] 29 pub struct RegionDisplayNames(pub icu_experimental::displaynames::RegionDisplayNames); 30 31 #[diplomat::rust_link(icu::displaynames::options::DisplayNamesOptions, Struct)] 32 #[diplomat::attr(supports = non_exhaustive_structs, rename = "DisplayNamesOptions")] 33 pub struct DisplayNamesOptionsV1 { 34 /// The optional formatting style to use for display name. 35 pub style: DiplomatOption<DisplayNamesStyle>, 36 /// The fallback return when the system does not have the 37 /// requested display name, defaults to "code". 38 pub fallback: DiplomatOption<DisplayNamesFallback>, 39 /// The language display kind, defaults to "dialect". 40 pub language_display: DiplomatOption<LanguageDisplay>, 41 } 42 43 #[diplomat::rust_link(icu::displaynames::options::Style, Enum)] 44 #[diplomat::enum_convert(icu_experimental::displaynames::Style, needs_wildcard)] 45 pub enum DisplayNamesStyle { 46 Narrow, 47 Short, 48 Long, 49 Menu, 50 } 51 52 #[diplomat::rust_link(icu::displaynames::options::Fallback, Enum)] 53 #[diplomat::enum_convert(icu_experimental::displaynames::Fallback, needs_wildcard)] 54 pub enum DisplayNamesFallback { 55 Code, 56 None, 57 } 58 59 #[diplomat::rust_link(icu::displaynames::options::LanguageDisplay, Enum)] 60 #[diplomat::enum_convert(icu_experimental::displaynames::LanguageDisplay, needs_wildcard)] 61 pub enum LanguageDisplay { 62 Dialect, 63 Standard, 64 } 65 66 impl LocaleDisplayNamesFormatter { 67 /// Creates a new `LocaleDisplayNamesFormatter` from locale data and an options bag using compiled data. 68 #[diplomat::rust_link(icu::displaynames::LocaleDisplayNamesFormatter::try_new, FnInStruct)] 69 #[diplomat::attr(all(supports = fallible_constructors, supports = non_exhaustive_structs), constructor)] 70 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors, not(supports = non_exhaustive_structs)), named_constructor = "v1")] 71 #[diplomat::attr(supports = non_exhaustive_structs, rename = "create")] 72 #[cfg(feature = "compiled_data")] create_v1( locale: &Locale, options: DisplayNamesOptionsV1, ) -> Result<Box<LocaleDisplayNamesFormatter>, DataError>73 pub fn create_v1( 74 locale: &Locale, 75 options: DisplayNamesOptionsV1, 76 ) -> Result<Box<LocaleDisplayNamesFormatter>, DataError> { 77 let prefs = (&locale.0).into(); 78 let options = icu_experimental::displaynames::DisplayNamesOptions::from(options); 79 80 Ok(Box::new(LocaleDisplayNamesFormatter( 81 icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new( 82 prefs, options, 83 )?, 84 ))) 85 } 86 87 /// Creates a new `LocaleDisplayNamesFormatter` from locale data and an options bag using a particular data source. 88 #[diplomat::rust_link(icu::displaynames::LocaleDisplayNamesFormatter::try_new, FnInStruct)] 89 #[diplomat::attr(supports = non_exhaustive_structs, rename = "create_with_provider")] 90 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors, supports = non_exhaustive_structs), named_constructor = "with_provider")] 91 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors, not(supports = non_exhaustive_structs)), named_constructor = "v1_with_provider")] 92 #[cfg(feature = "buffer_provider")] create_v1_with_provider( provider: &DataProvider, locale: &Locale, options: DisplayNamesOptionsV1, ) -> Result<Box<LocaleDisplayNamesFormatter>, DataError>93 pub fn create_v1_with_provider( 94 provider: &DataProvider, 95 locale: &Locale, 96 options: DisplayNamesOptionsV1, 97 ) -> Result<Box<LocaleDisplayNamesFormatter>, DataError> { 98 let prefs = (&locale.0).into(); 99 let options = icu_experimental::displaynames::DisplayNamesOptions::from(options); 100 101 Ok(Box::new(LocaleDisplayNamesFormatter( 102 icu_experimental::displaynames::LocaleDisplayNamesFormatter::try_new_with_buffer_provider(provider.get()?, prefs, 103 options, 104 )?, 105 ))) 106 } 107 108 /// Returns the locale-specific display name of a locale. 109 #[diplomat::rust_link(icu::displaynames::LocaleDisplayNamesFormatter::of, FnInStruct)] 110 // Experimental, do not generate in demo: 111 #[diplomat::attr(demo_gen, disable)] of(&self, locale: &Locale, write: &mut DiplomatWrite)112 pub fn of(&self, locale: &Locale, write: &mut DiplomatWrite) { 113 let _infallible = self.0.of(&locale.0).write_to(write); 114 } 115 } 116 117 impl RegionDisplayNames { 118 /// Creates a new `RegionDisplayNames` from locale data and an options bag using compiled data. 119 #[diplomat::rust_link(icu::displaynames::RegionDisplayNames::try_new, FnInStruct)] 120 #[diplomat::attr(all(supports = fallible_constructors, supports = non_exhaustive_structs), constructor)] 121 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors, not(supports = non_exhaustive_structs)), named_constructor = "v1")] 122 #[diplomat::attr(supports = non_exhaustive_structs, rename = "create")] 123 #[cfg(feature = "compiled_data")] create_v1( locale: &Locale, options: DisplayNamesOptionsV1, ) -> Result<Box<RegionDisplayNames>, DataError>124 pub fn create_v1( 125 locale: &Locale, 126 options: DisplayNamesOptionsV1, 127 ) -> Result<Box<RegionDisplayNames>, DataError> { 128 let prefs = (&locale.0).into(); 129 let options = icu_experimental::displaynames::DisplayNamesOptions::from(options); 130 Ok(Box::new(RegionDisplayNames( 131 icu_experimental::displaynames::RegionDisplayNames::try_new(prefs, options)?, 132 ))) 133 } 134 135 /// Creates a new `RegionDisplayNames` from locale data and an options bag using a particular data source. 136 #[diplomat::rust_link(icu::displaynames::RegionDisplayNames::try_new, FnInStruct)] 137 #[diplomat::attr(supports = non_exhaustive_structs, rename = "create_with_provider")] 138 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors, supports = non_exhaustive_structs), named_constructor = "with_provider")] 139 #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors, not(supports = non_exhaustive_structs)), named_constructor = "v1_with_provider")] 140 #[cfg(feature = "buffer_provider")] create_v1_with_provider( provider: &DataProvider, locale: &Locale, options: DisplayNamesOptionsV1, ) -> Result<Box<RegionDisplayNames>, DataError>141 pub fn create_v1_with_provider( 142 provider: &DataProvider, 143 locale: &Locale, 144 options: DisplayNamesOptionsV1, 145 ) -> Result<Box<RegionDisplayNames>, DataError> { 146 let prefs = (&locale.0).into(); 147 let options = icu_experimental::displaynames::DisplayNamesOptions::from(options); 148 Ok(Box::new(RegionDisplayNames( 149 icu_experimental::displaynames::RegionDisplayNames::try_new_with_buffer_provider( 150 provider.get()?, 151 prefs, 152 options, 153 )?, 154 ))) 155 } 156 157 /// Returns the locale specific display name of a region. 158 /// Note that the function returns an empty string in case the display name for a given 159 /// region code is not found. 160 #[diplomat::rust_link(icu::displaynames::RegionDisplayNames::of, FnInStruct)] 161 // Experimental, do not generate in demo: 162 #[diplomat::attr(demo_gen, disable)] of( &self, region: &DiplomatStr, write: &mut DiplomatWrite, ) -> Result<(), LocaleParseError>163 pub fn of( 164 &self, 165 region: &DiplomatStr, 166 write: &mut DiplomatWrite, 167 ) -> Result<(), LocaleParseError> { 168 let _infallible = self 169 .0 170 .of(icu_locale_core::subtags::Region::try_from_utf8(region)?) 171 .unwrap_or("") 172 .write_to(write); 173 Ok(()) 174 } 175 } 176 } 177 178 impl From<ffi::DisplayNamesOptionsV1> for icu_experimental::displaynames::DisplayNamesOptions { from( other: ffi::DisplayNamesOptionsV1, ) -> icu_experimental::displaynames::DisplayNamesOptions179 fn from( 180 other: ffi::DisplayNamesOptionsV1, 181 ) -> icu_experimental::displaynames::DisplayNamesOptions { 182 let mut options = icu_experimental::displaynames::DisplayNamesOptions::default(); 183 options.style = other.style.into_converted_option(); 184 options.fallback = other 185 .fallback 186 .into_converted_option() 187 .unwrap_or(options.fallback); 188 options.language_display = other 189 .language_display 190 .into_converted_option() 191 .unwrap_or(options.language_display); 192 options 193 } 194 } 195