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}