#![allow(clippy::exhaustive_structs)]
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;
#[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> {
#[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"),
}
}
}
#[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");
}
#[derive(Debug, PartialEq, Default)]
pub struct HelloWorldProvider;
impl HelloWorldProvider {
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", "你好世界"),
];
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)] 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> {
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,]);
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(),
)),
})
}
}
pub struct HelloWorldFormatter {
data: DataPayload<HelloWorldV1Marker>,
}
pub struct FormattedHelloWorld<'l> {
data: &'l HelloWorldV1<'l>,
}
impl HelloWorldFormatter {
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);
#[allow(clippy::needless_lifetimes)] pub fn format<'l>(&'l self) -> FormattedHelloWorld<'l> {
FormattedHelloWorld {
data: self.data.get(),
}
}
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()
}
}
writeable::impl_display_with_writeable!(FormattedHelloWorld<'_>);
#[cfg(feature = "datagen")]
impl IterableDataProvider<HelloWorldV1Marker> for HelloWorldProvider {
fn supported_locales(&self) -> Result<Vec<DataLocale>, DataError> {
#[allow(clippy::unwrap_used)] 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()
]
);
}