@@ -253,6 +253,83 @@ assert_eq!(formatter.format_to_string(&100007i64.into()), "100🐮007");
253253
254254Forking providers can be implemented using ` DataPayload::dynamic_cast ` . For an example, see that function's documentation.
255255
256+ ## Exporting Custom Data Markers
257+
258+ To add custom data markers to your baked data or postcard file, create a forking exportable provider:
259+
260+ ``` rust
261+ use icu :: locale :: locale;
262+ use icu :: plurals :: provider :: CardinalV1Marker ;
263+ use icu_provider :: prelude :: * ;
264+ use icu_provider :: DataMarker ;
265+ use icu_provider_adapters :: fork :: ForkByMarkerProvider ;
266+ use icu_provider_blob :: BlobDataProvider ;
267+ use icu_provider_export :: blob_exporter :: BlobExporter ;
268+ use icu_provider_export :: prelude :: * ;
269+ use icu_provider_source :: SourceDataProvider ;
270+ use std :: borrow :: Cow ;
271+ use std :: collections :: BTreeSet ;
272+
273+ #[icu_provider:: data_struct(marker(CustomMarker , " x/custom@1" ))]
274+ #[derive(Debug , PartialEq , serde:: Deserialize , serde:: Serialize , databake:: Bake )]
275+ #[databake(path = crate )]
276+ pub struct Custom <'data > {
277+ message : Cow <'data , str >,
278+ };
279+
280+ struct CustomProvider ;
281+ impl DataProvider <CustomMarker > for CustomProvider {
282+ fn load (& self , req : DataRequest ) -> Result <DataResponse <CustomMarker >, DataError > {
283+ Ok (DataResponse {
284+ metadata : Default :: default (),
285+ payload : DataPayload :: from_owned (Custom {
286+ message : format! (" Custom data for locale {}!" , req . id. locale). into (),
287+ }),
288+ })
289+ }
290+ }
291+
292+ impl IterableDataProvider <CustomMarker > for CustomProvider {
293+ fn iter_ids (& self ) -> Result <BTreeSet <DataIdentifierCow >, DataError > {
294+ Ok ([locale! (" es" ), locale! (" ja" )]
295+ . into_iter ()
296+ . map (DataLocale :: from )
297+ . map (DataIdentifierCow :: from_locale )
298+ . collect ())
299+ }
300+ }
301+
302+ icu_provider :: export :: make_exportable_provider! (CustomProvider , [CustomMarker ,]);
303+
304+ let icu4x_source_provider = SourceDataProvider :: new_latest_tested ();
305+ let custom_source_provider = CustomProvider ;
306+
307+ let mut buffer = Vec :: <u8 >:: new ();
308+
309+ ExportDriver :: new (
310+ [DataLocaleFamily :: FULL ],
311+ DeduplicationStrategy :: None . into (),
312+ LocaleFallbacker :: try_new_unstable (& icu4x_source_provider ). unwrap (),
313+ )
314+ . with_markers ([CardinalV1Marker :: INFO , CustomMarker :: INFO ])
315+ . export (
316+ & ForkByMarkerProvider :: new (icu4x_source_provider , custom_source_provider ),
317+ BlobExporter :: new_v2_with_sink (Box :: new (& mut buffer )),
318+ )
319+ . unwrap ();
320+
321+ let blob_provider = BlobDataProvider :: try_new_from_blob (buffer . into ()). unwrap ();
322+
323+ let locale = DataLocale :: from (& locale! (" ja" ));
324+ let req = DataRequest {
325+ id : DataIdentifierBorrowed :: for_locale (& locale ),
326+ metadata : Default :: default (),
327+ };
328+
329+ assert! (blob_provider . load_data (CardinalV1Marker :: INFO , req ). is_ok ());
330+ assert! (blob_provider . load_data (CustomMarker :: INFO , req ). is_ok ());
331+ ```
332+
256333## Accessing the Resolved Locale
257334
258335ICU4X objects do not store their "resolved locale" because that is not a well-defined concept. Components can load data from many sources, and fallbacks to parent locales or root does not necessarily mean that a locale is not supported.
0 commit comments