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 #[cfg(feature = "export")]
66 attributes_domain = "hello",
67);
68
69#[derive(Debug, PartialEq, Default)]
130pub struct HelloWorldProvider;
131
132impl HelloWorldProvider {
133 const DATA: &'static [(&'static str, &'static str, &'static str)] = &[
136 ("bn", "", "ওহে বিশ্ব"),
137 ("cs", "", "Ahoj světe"),
138 ("de", "", "Hallo Welt"),
139 ("de", "lowercase", "hallo welt"),
140 ("de", "uppercase", "HALLO WELT"),
141 ("de-AT", "", "Servus Welt"),
142 ("el", "", "Καλημέρα κόσμε"),
143 ("en", "", "Hello World"),
144 ("en-001", "", "Hello from 🗺️"),
146 ("en-002", "", "Hello from 🌍"),
148 ("en-019", "", "Hello from 🌎"),
150 ("en-142", "", "Hello from 🌏"),
152 ("en-GB", "", "Hello from 🇬🇧"),
154 ("en-GB-u-sd-gbeng", "", "Hello from 🏴"),
156 ("en", "lowercase", "hello world"),
157 ("en", "nested/part", "Hello Nested"),
158 ("en", "reverse", "Olleh Dlrow"),
159 ("en", "rotate1", "dHello Worl"),
160 ("en", "rotate2", "ldHello Wor"),
161 ("en", "rotate3", "rldHello Wo"),
162 ("en", "uppercase", "HELLO WORLD"),
163 ("eo", "", "Saluton, Mondo"),
164 ("fa", "", "سلام دنیا"),
165 ("fi", "", "hei maailma"),
166 ("is", "", "Halló, heimur"),
167 ("ja", "", "こんにちは世界"),
168 ("ja", "reverse", "界世はちにんこ"),
169 ("la", "", "Ave, munde"),
170 ("pt", "", "Olá, mundo"),
171 ("ro", "", "Salut, lume"),
172 ("ru", "", "Привет, мир"),
173 ("sr", "", "Поздрав свете"),
174 ("sr-Latn", "", "Pozdrav svete"),
175 ("vi", "", "Xin chào thế giới"),
176 ("zh", "", "你好世界"),
177 ];
178
179 #[cfg(feature = "deserialize_json")]
181 pub fn into_json_provider(self) -> HelloWorldJsonProvider {
182 HelloWorldJsonProvider
183 }
184}
185
186impl DataProvider<HelloWorldV1> for HelloWorldProvider {
187 fn load(&self, req: DataRequest) -> Result<DataResponse<HelloWorldV1>, DataError> {
188 let data = Self::DATA
189 .iter()
190 .find(|(l, a, _)| {
191 req.id.locale.strict_cmp(l.as_bytes()).is_eq()
192 && *a == req.id.marker_attributes.as_str()
193 })
194 .map(|(_, _, v)| v)
195 .ok_or_else(|| DataErrorKind::IdentifierNotFound.with_req(HelloWorldV1::INFO, req))?;
196 Ok(DataResponse {
197 metadata: DataResponseMetadata::default().with_checksum(1234),
198 payload: DataPayload::from_static_str(data),
199 })
200 }
201}
202
203impl DryDataProvider<HelloWorldV1> for HelloWorldProvider {
204 fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
205 self.load(req).map(|r| r.metadata)
206 }
207}
208
209impl DataPayload<HelloWorldV1> {
210 pub fn from_static_str(s: &'static str) -> DataPayload<HelloWorldV1> {
212 DataPayload::from_owned(HelloWorld {
213 message: Cow::Borrowed(s),
214 })
215 }
216}
217
218#[cfg(feature = "deserialize_json")]
219#[derive(Debug)]
240pub struct HelloWorldJsonProvider;
241
242#[cfg(feature = "deserialize_json")]
243impl DynamicDataProvider<BufferMarker> for HelloWorldJsonProvider {
244 fn load_data(
245 &self,
246 marker: DataMarkerInfo,
247 req: DataRequest,
248 ) -> Result<DataResponse<BufferMarker>, DataError> {
249 marker.match_marker(HelloWorldV1::INFO)?;
250 let result = HelloWorldProvider.load(req)?;
251 Ok(DataResponse {
252 metadata: DataResponseMetadata {
253 buffer_format: Some(icu_provider::buf::BufferFormat::Json),
254 ..result.metadata
255 },
256 #[expect(clippy::unwrap_used)] payload: DataPayload::from_owned_buffer(
258 serde_json::to_string(result.payload.get())
259 .unwrap()
260 .into_bytes()
261 .into_boxed_slice(),
262 ),
263 })
264 }
265}
266
267impl IterableDataProvider<HelloWorldV1> for HelloWorldProvider {
268 fn iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow<'_>>, DataError> {
269 #[expect(clippy::unwrap_used)] Ok(Self::DATA
271 .iter()
272 .map(|(l, a, _)| {
273 DataIdentifierCow::from_borrowed_and_owned(
274 DataMarkerAttributes::from_str_or_panic(a),
275 l.parse().unwrap(),
276 )
277 })
278 .collect())
279 }
280}
281
282#[cfg(feature = "export")]
283icu_provider::export::make_exportable_provider!(HelloWorldProvider, [HelloWorldV1,]);
284
285define_preferences!(
286 [Copy]
288 HelloWorldFormatterPreferences, {}
289);
290
291#[derive(Debug)]
311pub struct HelloWorldFormatter {
312 data: DataPayload<HelloWorldV1>,
313}
314
315#[derive(Debug)]
319pub struct FormattedHelloWorld<'l> {
320 data: &'l HelloWorld<'l>,
321}
322
323impl HelloWorldFormatter {
324 pub fn try_new(prefs: HelloWorldFormatterPreferences) -> Result<Self, DataError> {
328 Self::try_new_unstable(&HelloWorldProvider, prefs)
329 }
330
331 icu_provider::gen_buffer_data_constructors!((prefs: HelloWorldFormatterPreferences) -> error: DataError,
332 functions: [
333 try_new: skip,
334 try_new_with_buffer_provider,
335 try_new_unstable,
336 Self,
337 ]);
338
339 #[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::try_new)]
340 pub fn try_new_unstable<P>(
341 provider: &P,
342 prefs: HelloWorldFormatterPreferences,
343 ) -> Result<Self, DataError>
344 where
345 P: DataProvider<HelloWorldV1>,
346 {
347 let locale = HelloWorldV1::make_locale(prefs.locale_preferences);
348 let data = provider
349 .load(DataRequest {
350 id: DataIdentifierBorrowed::for_locale(&locale),
351 ..Default::default()
352 })?
353 .payload;
354 Ok(Self { data })
355 }
356
357 pub fn format<'l>(&'l self) -> FormattedHelloWorld<'l> {
359 FormattedHelloWorld {
360 data: self.data.get(),
361 }
362 }
363
364 pub fn format_to_string(&self) -> String {
366 self.format().write_to_string().into_owned()
367 }
368}
369
370impl Writeable for FormattedHelloWorld<'_> {
371 fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
372 self.data.message.write_to(sink)
373 }
374
375 fn writeable_borrow(&self) -> Option<&str> {
376 self.data.message.writeable_borrow()
377 }
378
379 fn writeable_length_hint(&self) -> writeable::LengthHint {
380 self.data.message.writeable_length_hint()
381 }
382}
383
384writeable::impl_display_with_writeable!(FormattedHelloWorld<'_>);
385
386#[cfg(feature = "export")]
387#[test]
388fn test_iter() {
389 use crate::IterableDataProvider;
390 use icu_locale_core::locale;
391
392 let ids = HelloWorldProvider.iter_ids().unwrap();
393
394 assert_eq!(ids.len(), HelloWorldProvider::DATA.len());
395
396 assert!(ids.contains(&DataIdentifierCow::from_borrowed_and_owned(
397 DataMarkerAttributes::from_str_or_panic("reverse"),
398 locale!("en").into()
399 )));
400}