1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
// This file is part of ICU4X. For terms of use, please see the file // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). //! Collection of iteration APIs for [`DataProvider`]. use crate::error::Error; use crate::prelude::*; use std::fmt::Debug; /// A provider that can iterate over all supported [`ResourceOptions`] for a certain key. /// /// Implementing this trait means that a [`DataProvider`] knows all of the data it can successfully /// return from a load request. pub trait IterableDataProviderCore { /// Given a [`ResourceKey`], returns a boxed iterator over [`ResourceOptions`]. fn supported_options_for_key( &self, resc_key: &ResourceKey, ) -> Result<Box<dyn Iterator<Item = ResourceOptions>>, Error>; } /// A super-trait combining [`DataProvider`] and [`IterableDataProviderCore`], auto-implemented /// for all types implementing both of those traits. pub trait IterableDataProvider<'d, T>: IterableDataProviderCore + DataProvider<'d, T> where T: ToOwned + ?Sized, <T as ToOwned>::Owned: Debug, { } impl<'d, S, T> IterableDataProvider<'d, T> for S where S: IterableDataProviderCore + DataProvider<'d, T>, T: ToOwned + ?Sized, <T as ToOwned>::Owned: Debug, { } /// A [`DataProvider`] whose supported keys are known statically at compile time. /// /// Implementing this trait means that a [`DataProvider`] is built to support a specific set of /// keys; for example, by transforming those keys from an external data source. /// /// TODO: When const_trait_impl is stable, most implementations of this trait should be const. pub trait KeyedDataProvider { /// Given a [`ResourceKey`], checks whether this type of [`DataProvider`] supports it. /// /// Returns Ok if the key is supported, or an Error with more information if not. The Error /// should be either [`UnsupportedCategory`] or [`UnsupportedResourceKey`]. /// /// [`UnsupportedCategory`]: crate::error::Error::UnsupportedCategory /// [`UnsupportedResourceKey`]: crate::error::Error::UnsupportedResourceKey fn supports_key(resc_key: &ResourceKey) -> Result<(), Error>; /// Auto-implemented function that enables chaining of [`KeyedDataProviders`] while preserving /// [`UnsupportedResourceKey`]. /// /// [`KeyedDataProviders`]: KeyedDataProvider /// [`UnsupportedResourceKey`]: crate::error::Error::UnsupportedResourceKey /// /// # Examples /// /// ```ignore /// DataProviderA::supports_key(resc_key) /// .or_else(|err| DataProviderB::or_else_supports_key(err, resc_key)) /// .or_else(|err| DataProviderC::or_else_supports_key(err, resc_key)) /// ``` fn or_else_supports_key(err: Error, resc_key: &ResourceKey) -> Result<(), Error> { match Self::supports_key(resc_key) { Ok(()) => Ok(()), Err(new_err) => { if let Error::UnsupportedResourceKey(_) = err { Err(err) } else { Err(new_err) } } } } }