diff options
Diffstat (limited to 'vendor/icu_provider/src/hello_world.rs')
-rw-r--r-- | vendor/icu_provider/src/hello_world.rs | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/vendor/icu_provider/src/hello_world.rs b/vendor/icu_provider/src/hello_world.rs new file mode 100644 index 000000000..5fa671d84 --- /dev/null +++ b/vendor/icu_provider/src/hello_world.rs @@ -0,0 +1,307 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +//! Data provider returning multilingual "Hello World" strings for testing. + +#![allow(clippy::exhaustive_structs)] // data struct module + +use crate::buf::BufferFormat; +#[cfg(feature = "datagen")] +use crate::datagen::IterableDataProvider; +use crate::helpers; +use crate::prelude::*; +use crate::yoke::{self, *}; +use crate::zerofrom::{self, *}; +use alloc::borrow::Cow; +use alloc::string::String; +use core::fmt::Debug; +use writeable::Writeable; + +/// A struct containing "Hello World" in the requested language. +#[derive(Debug, PartialEq, Clone, Yokeable, ZeroFrom)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))] +#[cfg_attr(feature = "datagen", databake(path = icu_provider::hello_world))] +pub struct HelloWorldV1<'data> { + /// The translation of "Hello World". + #[cfg_attr(feature = "serde", serde(borrow))] + pub message: Cow<'data, str>, +} + +impl Default for HelloWorldV1<'_> { + fn default() -> Self { + HelloWorldV1 { + message: Cow::Borrowed("(und) Hello World"), + } + } +} + +/// Marker type for [`HelloWorldV1`]. +#[cfg_attr(feature = "datagen", derive(Default, databake::Bake))] +#[cfg_attr(feature = "datagen", databake(path = icu_provider::hello_world))] +pub struct HelloWorldV1Marker; + +impl DataMarker for HelloWorldV1Marker { + type Yokeable = HelloWorldV1<'static>; +} + +impl KeyedDataMarker for HelloWorldV1Marker { + const KEY: DataKey = crate::data_key!("core/helloworld@1"); +} + +/// A data provider returning Hello World strings in different languages. +/// +/// Mostly useful for testing. +/// +/// # Examples +/// +/// ``` +/// use icu_locid::locale; +/// use icu_provider::hello_world::*; +/// use icu_provider::prelude::*; +/// +/// let german_hello_world: DataPayload<HelloWorldV1Marker> = +/// HelloWorldProvider +/// .load(DataRequest { +/// locale: &locale!("de").into(), +/// metadata: Default::default(), +/// }) +/// .expect("Loading should succeed") +/// .take_payload() +/// .expect("Data should be present"); +/// +/// assert_eq!("Hallo Welt", german_hello_world.get().message); +/// ``` +#[derive(Debug, PartialEq, Default)] +pub struct HelloWorldProvider; + +impl HelloWorldProvider { + // Data from https://en.wiktionary.org/wiki/Hello_World#Translations + // Keep this sorted! + const DATA: &'static [(&'static str, &'static str)] = &[ + ("bn", "ওহে বিশ্ব"), + ("cs", "Ahoj světe"), + ("de", "Hallo Welt"), + ("el", "Καλημέρα κόσμε"), + ("en", "Hello World"), + ("eo", "Saluton, Mondo"), + ("fa", "سلام دنیا"), + ("fi", "hei maailma"), + ("is", "Halló, heimur"), + ("ja", "こんにちは世界"), + ("la", "Ave, munde"), + ("pt", "Olá, mundo"), + ("ro", "Salut, lume"), + ("ru", "Привет, мир"), + ("vi", "Xin chào thế giới"), + ("zh", "你好世界"), + ]; + + /// Converts this provider into one that serves JSON blobs of the same data. + pub fn into_json_provider(self) -> HelloWorldJsonProvider { + HelloWorldJsonProvider(self) + } +} + +impl DataProvider<HelloWorldV1Marker> for HelloWorldProvider { + fn load(&self, req: DataRequest) -> Result<DataResponse<HelloWorldV1Marker>, DataError> { + #[allow(clippy::indexing_slicing)] // binary_search + let data = Self::DATA + .binary_search_by(|(k, _)| req.locale.strict_cmp(k.as_bytes()).reverse()) + .map(|i| Self::DATA[i].1) + .map(|s| HelloWorldV1 { + message: Cow::Borrowed(s), + }) + .map_err(|_| DataErrorKind::MissingLocale.with_req(HelloWorldV1Marker::KEY, req))?; + Ok(DataResponse { + metadata: Default::default(), + payload: Some(DataPayload::from_owned(data)), + }) + } +} + +impl DataPayload<HelloWorldV1Marker> { + /// Make a [`DataPayload`]`<`[`HelloWorldV1Marker`]`>` from a static string slice. + pub fn from_static_str(s: &'static str) -> DataPayload<HelloWorldV1Marker> { + DataPayload::from_owned(HelloWorldV1 { + message: Cow::Borrowed(s), + }) + } +} + +#[cfg(not(feature = "datagen"))] +impl_dynamic_data_provider!(HelloWorldProvider, [HelloWorldV1Marker,], AnyMarker); + +#[cfg(feature = "datagen")] +make_exportable_provider!(HelloWorldProvider, [HelloWorldV1Marker,]); + +/// A data provider returning Hello World strings in different languages as JSON blobs. +/// +/// Mostly useful for testing. +/// +/// # Examples +/// +/// ``` +/// use icu_locid::locale; +/// use icu_provider::hello_world::*; +/// use icu_provider::prelude::*; +/// +/// let german_hello_world = HelloWorldProvider +/// .into_json_provider() +/// .load_buffer(HelloWorldV1Marker::KEY, DataRequest { +/// locale: &locale!("de").into(), +/// metadata: Default::default(), +/// }) +/// .expect("Loading should succeed") +/// .take_payload() +/// .expect("Data should be present"); +/// +/// assert_eq!(b"{\"message\":\"Hallo Welt\"}", german_hello_world.get()); +pub struct HelloWorldJsonProvider(HelloWorldProvider); + +impl BufferProvider for HelloWorldJsonProvider { + fn load_buffer( + &self, + key: DataKey, + req: DataRequest, + ) -> Result<DataResponse<BufferMarker>, DataError> { + key.match_key(HelloWorldV1Marker::KEY)?; + let result = self.0.load(req)?; + let (mut metadata, old_payload) = + DataResponse::<HelloWorldV1Marker>::take_metadata_and_payload(result)?; + metadata.buffer_format = Some(BufferFormat::Json); + let mut buffer = String::new(); + buffer.push_str("{\"message\":\""); + helpers::escape_for_json(&old_payload.get().message, &mut buffer); + buffer.push_str("\"}"); + Ok(DataResponse { + metadata, + payload: Some(DataPayload::from_owned_buffer( + buffer.into_bytes().into_boxed_slice(), + )), + }) + } +} + +/// A type that formats localized "hello world" strings. +/// +/// This type is intended to take the shape of a typical ICU4X formatter API. +/// +/// # Examples +/// +/// ``` +/// use icu_locid::locale; +/// use icu_provider::hello_world::{HelloWorldFormatter, HelloWorldProvider}; +/// use writeable::assert_writeable_eq; +/// +/// let fmt = HelloWorldFormatter::try_new_unstable( +/// &HelloWorldProvider, +/// &locale!("eo").into(), +/// ) +/// .expect("locale exists"); +/// +/// assert_writeable_eq!(fmt.format(), "Saluton, Mondo"); +/// ``` +pub struct HelloWorldFormatter { + data: DataPayload<HelloWorldV1Marker>, +} + +/// A formatted hello world message. Implements [`Writeable`]. +/// +/// For an example, see [`HelloWorldFormatter`]. +pub struct FormattedHelloWorld<'l> { + data: &'l HelloWorldV1<'l>, +} + +impl HelloWorldFormatter { + /// Creates a new [`HelloWorldFormatter`] for the specified locale. + /// + /// See [`HelloWorldFormatter`] for an example. + /// + /// [📚 Help choosing a constructor](crate::constructors) + /// <div class="stab unstable"> + /// ⚠️ The bounds on this function may change over time, including in SemVer minor releases. + /// </div> + pub fn try_new_unstable<P>(provider: &P, locale: &DataLocale) -> Result<Self, DataError> + where + P: DataProvider<HelloWorldV1Marker>, + { + let data = provider + .load(DataRequest { + locale, + metadata: Default::default(), + })? + .take_payload()?; + Ok(Self { data }) + } + + crate::gen_any_buffer_constructors!(locale: include, options: skip, error: DataError); + + /// Formats a hello world message, returning a [`FormattedHelloWorld`]. + #[allow(clippy::needless_lifetimes)] // documentary example + pub fn format<'l>(&'l self) -> FormattedHelloWorld<'l> { + FormattedHelloWorld { + data: self.data.get(), + } + } + + /// Formats a hello world message, returning a [`String`]. + pub fn format_to_string(&self) -> String { + self.format().write_to_string().into_owned() + } +} + +impl<'l> Writeable for FormattedHelloWorld<'l> { + fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result { + self.data.message.write_to(sink) + } + + fn write_to_string(&self) -> Cow<str> { + self.data.message.clone() + } + + fn writeable_length_hint(&self) -> writeable::LengthHint { + self.data.message.writeable_length_hint() + } +} + +#[cfg(feature = "datagen")] +impl IterableDataProvider<HelloWorldV1Marker> for HelloWorldProvider { + fn supported_locales(&self) -> Result<Vec<DataLocale>, DataError> { + #[allow(clippy::unwrap_used)] // datagen + Ok(Self::DATA + .iter() + .map(|(s, _)| s.parse::<icu_locid::LanguageIdentifier>().unwrap()) + .map(DataLocale::from) + .collect()) + } +} + +#[cfg(feature = "datagen")] +#[test] +fn test_iter() { + use icu_locid::locale; + + assert_eq!( + HelloWorldProvider.supported_locales().unwrap(), + vec![ + locale!("bn").into(), + locale!("cs").into(), + locale!("de").into(), + locale!("el").into(), + locale!("en").into(), + locale!("eo").into(), + locale!("fa").into(), + locale!("fi").into(), + locale!("is").into(), + locale!("ja").into(), + locale!("la").into(), + locale!("pt").into(), + locale!("ro").into(), + locale!("ru").into(), + locale!("vi").into(), + locale!("zh").into() + ] + ); +} |