1#![allow(clippy::exhaustive_structs)] use crate as icu_provider;
10
11use crate::prelude::*;
12use alloc::borrow::Cow;
13use alloc::string::String;
14use core::fmt::Debug;
15use writeable::Writeable;
16use yoke::*;
17use zerofrom::*;
18
19#[derive(Debug, PartialEq, Clone, Yokeable, ZeroFrom)]
21#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
22#[cfg_attr(
23 any(feature = "deserialize_json", feature = "datagen"),
24 derive(serde::Serialize)
25)]
26#[cfg_attr(feature = "datagen", derive(databake::Bake))]
27#[cfg_attr(feature = "datagen", databake(path = icu_provider::hello_world))]
28pub struct HelloWorldV1<'data> {
29 #[cfg_attr(feature = "serde", serde(borrow))]
31 pub message: Cow<'data, str>,
32}
33
34impl Default for HelloWorldV1<'_> {
35 fn default() -> Self {
36 HelloWorldV1 {
37 message: Cow::Borrowed("(und) Hello World"),
38 }
39 }
40}
41
42#[cfg_attr(feature = "datagen", derive(Default, databake::Bake))]
44#[cfg_attr(feature = "datagen", databake(path = icu_provider::hello_world))]
45#[derive(Debug)]
46pub struct HelloWorldV1Marker;
47
48impl DataMarker for HelloWorldV1Marker {
49 type Yokeable = HelloWorldV1<'static>;
50}
51
52impl KeyedDataMarker for HelloWorldV1Marker {
53 const KEY: DataKey = icu_provider::data_key!("core/helloworld@1");
54}
55
56#[derive(Debug, PartialEq, Default)]
99pub struct HelloWorldProvider;
100
101impl HelloWorldProvider {
102 const DATA: &'static [(&'static str, &'static str)] = &[
105 ("bn", "ওহে বিশ্ব"),
106 ("cs", "Ahoj světe"),
107 ("de", "Hallo Welt"),
108 ("de-AT", "Servus Welt"),
109 ("el", "Καλημέρα κόσμε"),
110 ("en", "Hello World"),
111 ("en-001", "Hello from 🗺️"), ("en-002", "Hello from 🌍"), ("en-019", "Hello from 🌎"), ("en-142", "Hello from 🌏"), ("en-GB", "Hello from 🇬🇧"), ("en-GB-u-sd-gbeng", "Hello from 🏴"), ("en-x-reverse", "Olleh Dlrow"),
118 ("eo", "Saluton, Mondo"),
119 ("fa", "سلام دنیا"),
120 ("fi", "hei maailma"),
121 ("is", "Halló, heimur"),
122 ("ja", "こんにちは世界"),
123 ("ja-x-reverse", "界世はちにんこ"),
124 ("la", "Ave, munde"),
125 ("pt", "Olá, mundo"),
126 ("ro", "Salut, lume"),
127 ("ru", "Привет, мир"),
128 ("sr", "Поздрав свете"),
129 ("sr-Latn", "Pozdrav svete"),
130 ("vi", "Xin chào thế giới"),
131 ("zh", "你好世界"),
132 ];
133
134 #[cfg(feature = "deserialize_json")]
136 pub fn into_json_provider(self) -> HelloWorldJsonProvider {
137 HelloWorldJsonProvider
138 }
139}
140
141impl DataProvider<HelloWorldV1Marker> for HelloWorldProvider {
142 fn load(&self, req: DataRequest) -> Result<DataResponse<HelloWorldV1Marker>, DataError> {
143 #[allow(clippy::indexing_slicing)] let data = Self::DATA
145 .binary_search_by(|(k, _)| req.locale.strict_cmp(k.as_bytes()).reverse())
146 .map(|i| Self::DATA[i].1)
147 .map_err(|_| DataErrorKind::MissingLocale.with_req(HelloWorldV1Marker::KEY, req))?;
148 Ok(DataResponse {
149 metadata: Default::default(),
150 payload: Some(DataPayload::from_static_str(data)),
151 })
152 }
153}
154
155impl DataPayload<HelloWorldV1Marker> {
156 pub fn from_static_str(s: &'static str) -> DataPayload<HelloWorldV1Marker> {
158 DataPayload::from_owned(HelloWorldV1 {
159 message: Cow::Borrowed(s),
160 })
161 }
162}
163
164#[cfg(not(feature = "datagen"))]
166icu_provider::impl_dynamic_data_provider!(HelloWorldProvider, [HelloWorldV1Marker,], AnyMarker);
167
168#[cfg(feature = "deserialize_json")]
169#[derive(Debug)]
192pub struct HelloWorldJsonProvider;
193
194#[cfg(feature = "deserialize_json")]
195impl BufferProvider for HelloWorldJsonProvider {
196 fn load_buffer(
197 &self,
198 key: DataKey,
199 req: DataRequest,
200 ) -> Result<DataResponse<BufferMarker>, DataError> {
201 key.match_key(HelloWorldV1Marker::KEY)?;
202 let result = HelloWorldProvider.load(req)?;
203 let (mut metadata, old_payload) =
204 DataResponse::<HelloWorldV1Marker>::take_metadata_and_payload(result)?;
205 metadata.buffer_format = Some(icu_provider::buf::BufferFormat::Json);
206 #[allow(clippy::unwrap_used)] Ok(DataResponse {
208 metadata,
209 payload: Some(DataPayload::from_owned_buffer(
210 serde_json::to_string(old_payload.get())
211 .unwrap()
212 .into_bytes()
213 .into_boxed_slice(),
214 )),
215 })
216 }
217}
218
219#[cfg(feature = "datagen")]
220impl icu_provider::datagen::IterableDataProvider<HelloWorldV1Marker> for HelloWorldProvider {
221 fn supported_locales(&self) -> Result<Vec<DataLocale>, DataError> {
222 #[allow(clippy::unwrap_used)] Ok(Self::DATA.iter().map(|(s, _)| s.parse().unwrap()).collect())
224 }
225}
226
227#[cfg(feature = "datagen")]
228icu_provider::make_exportable_provider!(HelloWorldProvider, [HelloWorldV1Marker,]);
229
230#[derive(Debug)]
250pub struct HelloWorldFormatter {
251 data: DataPayload<HelloWorldV1Marker>,
252}
253
254#[derive(Debug)]
258pub struct FormattedHelloWorld<'l> {
259 data: &'l HelloWorldV1<'l>,
260}
261
262impl HelloWorldFormatter {
263 pub fn try_new(locale: &DataLocale) -> Result<Self, DataError> {
267 Self::try_new_unstable(&HelloWorldProvider, locale)
268 }
269
270 icu_provider::gen_any_buffer_data_constructors!(locale: include, options: skip, error: DataError,
271 #[cfg(skip)]
272 functions: [
273 try_new,
274 try_new_with_any_provider,
275 try_new_with_buffer_provider,
276 try_new_unstable,
277 Self,
278 ]);
279
280 #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
281 pub fn try_new_unstable<P>(provider: &P, locale: &DataLocale) -> Result<Self, DataError>
282 where
283 P: DataProvider<HelloWorldV1Marker>,
284 {
285 let data = provider
286 .load(DataRequest {
287 locale,
288 metadata: Default::default(),
289 })?
290 .take_payload()?;
291 Ok(Self { data })
292 }
293
294 #[allow(clippy::needless_lifetimes)] pub fn format<'l>(&'l self) -> FormattedHelloWorld<'l> {
297 FormattedHelloWorld {
298 data: self.data.get(),
299 }
300 }
301
302 pub fn format_to_string(&self) -> String {
304 self.format().write_to_string().into_owned()
305 }
306}
307
308impl<'l> Writeable for FormattedHelloWorld<'l> {
309 fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
310 self.data.message.write_to(sink)
311 }
312
313 fn write_to_string(&self) -> Cow<str> {
314 self.data.message.clone()
315 }
316
317 fn writeable_length_hint(&self) -> writeable::LengthHint {
318 self.data.message.writeable_length_hint()
319 }
320}
321
322writeable::impl_display_with_writeable!(FormattedHelloWorld<'_>);
323
324#[cfg(feature = "datagen")]
325#[test]
326fn test_iter() {
327 use crate::datagen::IterableDataProvider;
328 use icu_locid::locale;
329
330 assert_eq!(
331 HelloWorldProvider.supported_locales().unwrap(),
332 vec![
333 locale!("bn").into(),
334 locale!("cs").into(),
335 locale!("de").into(),
336 locale!("de-AT").into(),
337 locale!("el").into(),
338 locale!("en").into(),
339 locale!("en-001").into(),
340 locale!("en-002").into(),
341 locale!("en-019").into(),
342 locale!("en-142").into(),
343 locale!("en-GB").into(),
344 locale!("en-GB-u-sd-gbeng").into(),
345 "en-x-reverse".parse().unwrap(),
346 locale!("eo").into(),
347 locale!("fa").into(),
348 locale!("fi").into(),
349 locale!("is").into(),
350 locale!("ja").into(),
351 "ja-x-reverse".parse().unwrap(),
352 locale!("la").into(),
353 locale!("pt").into(),
354 locale!("ro").into(),
355 locale!("ru").into(),
356 locale!("sr").into(),
357 locale!("sr-Latn").into(),
358 locale!("vi").into(),
359 locale!("zh").into()
360 ]
361 );
362}