1#![allow(clippy::exhaustive_structs)] use crate as icu_provider;
10
11use crate::prelude::*;
12use alloc::borrow::Cow;
13use alloc::collections::BTreeSet;
14use alloc::string::String;
15use core::fmt::Debug;
16use icu_locale_core::preferences::define_preferences;
17use writeable::Writeable;
18use yoke::*;
19use zerofrom::*;
20
21#[derive(Debug, PartialEq, Clone, Yokeable, ZeroFrom)]
23#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
24#[cfg_attr(
25 any(feature = "deserialize_json", feature = "export"),
26 derive(serde::Serialize)
27)]
28#[cfg_attr(feature = "export", derive(databake::Bake))]
29#[cfg_attr(feature = "export", databake(path = icu_provider::hello_world))]
30pub struct HelloWorld<'data> {
31 #[cfg_attr(feature = "serde", serde(borrow))]
33 pub message: Cow<'data, str>,
34}
35
36impl Default for HelloWorld<'_> {
37 fn default() -> Self {
38 HelloWorld {
39 message: Cow::Borrowed("(und) Hello World"),
40 }
41 }
42}
43
44impl<'a> ZeroFrom<'a, str> for HelloWorld<'a> {
45 fn zero_from(message: &'a str) -> Self {
46 HelloWorld {
47 message: Cow::Borrowed(message),
48 }
49 }
50}
51
52crate::data_struct!(
53 HelloWorld<'data>,
54 varule: str,
55 #[cfg(feature = "export")]
56 encode_as_varule: |v: &HelloWorld<'_>| &*v.message
57);
58
59data_marker!(
60 #[derive(Debug)]
62 HelloWorldV1,
63 HelloWorld<'static>,
64 has_checksum = true,
65);
66
67#[derive(Debug, PartialEq, Default)]
108pub struct HelloWorldProvider;
109
110impl HelloWorldProvider {
111 const DATA: &'static [(&'static str, &'static str, &'static str)] = &[
114 ("bn", "", "ওহে বিশ্ব"),
115 ("cs", "", "Ahoj světe"),
116 ("de", "", "Hallo Welt"),
117 ("de-AT", "", "Servus Welt"),
118 ("el", "", "Καλημέρα κόσμε"),
119 ("en", "", "Hello World"),
120 ("en-001", "", "Hello from 🗺️"),
122 ("en-002", "", "Hello from 🌍"),
124 ("en-019", "", "Hello from 🌎"),
126 ("en-142", "", "Hello from 🌏"),
128 ("en-GB", "", "Hello from 🇬🇧"),
130 ("en-GB-u-sd-gbeng", "", "Hello from 🏴"),
132 ("en", "reverse", "Olleh Dlrow"),
133 ("eo", "", "Saluton, Mondo"),
134 ("fa", "", "سلام دنیا"),
135 ("fi", "", "hei maailma"),
136 ("is", "", "Halló, heimur"),
137 ("ja", "", "こんにちは世界"),
138 ("ja", "reverse", "界世はちにんこ"),
139 ("la", "", "Ave, munde"),
140 ("pt", "", "Olá, mundo"),
141 ("ro", "", "Salut, lume"),
142 ("ru", "", "Привет, мир"),
143 ("sr", "", "Поздрав свете"),
144 ("sr-Latn", "", "Pozdrav svete"),
145 ("vi", "", "Xin chào thế giới"),
146 ("zh", "", "你好世界"),
147 ];
148
149 #[cfg(feature = "deserialize_json")]
151 pub fn into_json_provider(self) -> HelloWorldJsonProvider {
152 HelloWorldJsonProvider
153 }
154}
155
156impl DataProvider<HelloWorldV1> for HelloWorldProvider {
157 fn load(&self, req: DataRequest) -> Result<DataResponse<HelloWorldV1>, DataError> {
158 #[allow(clippy::indexing_slicing)] let data = Self::DATA
160 .iter()
161 .find(|(l, a, _)| {
162 req.id.locale.strict_cmp(l.as_bytes()).is_eq()
163 && *a == req.id.marker_attributes.as_str()
164 })
165 .map(|(_, _, v)| v)
166 .ok_or_else(|| DataErrorKind::IdentifierNotFound.with_req(HelloWorldV1::INFO, req))?;
167 Ok(DataResponse {
168 metadata: DataResponseMetadata::default().with_checksum(1234),
169 payload: DataPayload::from_static_str(data),
170 })
171 }
172}
173
174impl DryDataProvider<HelloWorldV1> for HelloWorldProvider {
175 fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
176 self.load(req).map(|r| r.metadata)
177 }
178}
179
180impl DataPayload<HelloWorldV1> {
181 pub fn from_static_str(s: &'static str) -> DataPayload<HelloWorldV1> {
183 DataPayload::from_owned(HelloWorld {
184 message: Cow::Borrowed(s),
185 })
186 }
187}
188
189#[cfg(feature = "deserialize_json")]
190#[derive(Debug)]
211pub struct HelloWorldJsonProvider;
212
213#[cfg(feature = "deserialize_json")]
214impl DynamicDataProvider<BufferMarker> for HelloWorldJsonProvider {
215 fn load_data(
216 &self,
217 marker: DataMarkerInfo,
218 req: DataRequest,
219 ) -> Result<DataResponse<BufferMarker>, DataError> {
220 marker.match_marker(HelloWorldV1::INFO)?;
221 let result = HelloWorldProvider.load(req)?;
222 Ok(DataResponse {
223 metadata: DataResponseMetadata {
224 buffer_format: Some(icu_provider::buf::BufferFormat::Json),
225 ..result.metadata
226 },
227 #[allow(clippy::unwrap_used)] payload: DataPayload::from_owned_buffer(
229 serde_json::to_string(result.payload.get())
230 .unwrap()
231 .into_bytes()
232 .into_boxed_slice(),
233 ),
234 })
235 }
236}
237
238impl IterableDataProvider<HelloWorldV1> for HelloWorldProvider {
239 fn iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow>, DataError> {
240 #[allow(clippy::unwrap_used)] Ok(Self::DATA
242 .iter()
243 .map(|(l, a, _)| {
244 DataIdentifierCow::from_borrowed_and_owned(
245 DataMarkerAttributes::from_str_or_panic(a),
246 l.parse().unwrap(),
247 )
248 })
249 .collect())
250 }
251}
252
253#[cfg(feature = "export")]
254icu_provider::export::make_exportable_provider!(HelloWorldProvider, [HelloWorldV1,]);
255
256define_preferences!(
257 [Copy]
259 HelloWorldFormatterPreferences, {}
260);
261
262#[derive(Debug)]
282pub struct HelloWorldFormatter {
283 data: DataPayload<HelloWorldV1>,
284}
285
286#[derive(Debug)]
290pub struct FormattedHelloWorld<'l> {
291 data: &'l HelloWorld<'l>,
292}
293
294impl HelloWorldFormatter {
295 pub fn try_new(prefs: HelloWorldFormatterPreferences) -> Result<Self, DataError> {
299 Self::try_new_unstable(&HelloWorldProvider, prefs)
300 }
301
302 icu_provider::gen_buffer_data_constructors!((prefs: HelloWorldFormatterPreferences) -> error: DataError,
303 functions: [
304 try_new: skip,
305 try_new_with_buffer_provider,
306 try_new_unstable,
307 Self,
308 ]);
309
310 #[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
311 pub fn try_new_unstable<P>(
312 provider: &P,
313 prefs: HelloWorldFormatterPreferences,
314 ) -> Result<Self, DataError>
315 where
316 P: DataProvider<HelloWorldV1>,
317 {
318 let locale = HelloWorldV1::make_locale(prefs.locale_preferences);
319 let data = provider
320 .load(DataRequest {
321 id: crate::request::DataIdentifierBorrowed::for_locale(&locale),
322 ..Default::default()
323 })?
324 .payload;
325 Ok(Self { data })
326 }
327
328 #[allow(clippy::needless_lifetimes)] pub fn format<'l>(&'l self) -> FormattedHelloWorld<'l> {
331 FormattedHelloWorld {
332 data: self.data.get(),
333 }
334 }
335
336 pub fn format_to_string(&self) -> String {
338 self.format().write_to_string().into_owned()
339 }
340}
341
342impl Writeable for FormattedHelloWorld<'_> {
343 fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
344 self.data.message.write_to(sink)
345 }
346
347 fn write_to_string(&self) -> Cow<str> {
348 self.data.message.clone()
349 }
350
351 fn writeable_length_hint(&self) -> writeable::LengthHint {
352 self.data.message.writeable_length_hint()
353 }
354}
355
356writeable::impl_display_with_writeable!(FormattedHelloWorld<'_>);
357
358#[cfg(feature = "export")]
359#[test]
360fn test_iter() {
361 use crate::IterableDataProvider;
362 use icu_locale_core::locale;
363
364 assert_eq!(
365 HelloWorldProvider.iter_ids().unwrap(),
366 BTreeSet::from_iter([
367 DataIdentifierCow::from_locale(locale!("bn").into()),
368 DataIdentifierCow::from_locale(locale!("cs").into()),
369 DataIdentifierCow::from_locale(locale!("de").into()),
370 DataIdentifierCow::from_locale(locale!("de-AT").into()),
371 DataIdentifierCow::from_locale(locale!("el").into()),
372 DataIdentifierCow::from_locale(locale!("en").into()),
373 DataIdentifierCow::from_locale(locale!("en-001").into()),
374 DataIdentifierCow::from_locale(locale!("en-002").into()),
375 DataIdentifierCow::from_locale(locale!("en-019").into()),
376 DataIdentifierCow::from_locale(locale!("en-142").into()),
377 DataIdentifierCow::from_locale(locale!("en-GB").into()),
378 DataIdentifierCow::from_locale(locale!("en-GB-u-sd-gbeng").into()),
379 DataIdentifierCow::from_borrowed_and_owned(
380 DataMarkerAttributes::from_str_or_panic("reverse"),
381 locale!("en").into()
382 ),
383 DataIdentifierCow::from_locale(locale!("eo").into()),
384 DataIdentifierCow::from_locale(locale!("fa").into()),
385 DataIdentifierCow::from_locale(locale!("fi").into()),
386 DataIdentifierCow::from_locale(locale!("is").into()),
387 DataIdentifierCow::from_locale(locale!("ja").into()),
388 DataIdentifierCow::from_borrowed_and_owned(
389 DataMarkerAttributes::from_str_or_panic("reverse"),
390 locale!("ja").into()
391 ),
392 DataIdentifierCow::from_locale(locale!("la").into()),
393 DataIdentifierCow::from_locale(locale!("pt").into()),
394 DataIdentifierCow::from_locale(locale!("ro").into()),
395 DataIdentifierCow::from_locale(locale!("ru").into()),
396 DataIdentifierCow::from_locale(locale!("sr").into()),
397 DataIdentifierCow::from_locale(locale!("sr-Latn").into()),
398 DataIdentifierCow::from_locale(locale!("vi").into()),
399 DataIdentifierCow::from_locale(locale!("zh").into()),
400 ])
401 );
402}