• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of ICU4X. For terms of use, please see the file
2 // called LICENSE at the top level of the ICU4X source tree
3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4 
5 use core::marker::PhantomData;
6 use yoke::Yokeable;
7 
8 use crate::prelude::*;
9 
10 /// A data provider that loads data for a specific [`DataMarkerInfo`].
11 pub trait DataProvider<M>
12 where
13     M: DataMarker,
14 {
15     /// Query the provider for data, returning the result.
16     ///
17     /// Returns [`Ok`] if the request successfully loaded data. If data failed to load, returns an
18     /// Error with more information.
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>19     fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>;
20 }
21 
22 impl<M, P> DataProvider<M> for &P
23 where
24     M: DataMarker,
25     P: DataProvider<M> + ?Sized,
26 {
27     #[inline]
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>28     fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
29         (*self).load(req)
30     }
31 }
32 
33 #[cfg(feature = "alloc")]
34 impl<M, P> DataProvider<M> for alloc::boxed::Box<P>
35 where
36     M: DataMarker,
37     P: DataProvider<M> + ?Sized,
38 {
39     #[inline]
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>40     fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
41         (**self).load(req)
42     }
43 }
44 
45 #[cfg(feature = "alloc")]
46 impl<M, P> DataProvider<M> for alloc::rc::Rc<P>
47 where
48     M: DataMarker,
49     P: DataProvider<M> + ?Sized,
50 {
51     #[inline]
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>52     fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
53         (**self).load(req)
54     }
55 }
56 
57 #[cfg(target_has_atomic = "ptr")]
58 #[cfg(feature = "alloc")]
59 impl<M, P> DataProvider<M> for alloc::sync::Arc<P>
60 where
61     M: DataMarker,
62     P: DataProvider<M> + ?Sized,
63 {
64     #[inline]
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>65     fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
66         (**self).load(req)
67     }
68 }
69 
70 /// A data provider that can determine whether it can load a particular data identifier,
71 /// potentially cheaper than actually performing the load.
72 pub trait DryDataProvider<M: DataMarker>: DataProvider<M> {
73     /// This method goes through the motions of [`load`], but only returns the metadata.
74     ///
75     /// If `dry_load` returns an error, [`load`] must return the same error, but
76     /// not vice-versa. Concretely, [`load`] could return deserialization or I/O errors
77     /// that `dry_load` cannot predict.
78     ///
79     /// [`load`]: DataProvider::load
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>80     fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>;
81 }
82 
83 impl<M, P> DryDataProvider<M> for &P
84 where
85     M: DataMarker,
86     P: DryDataProvider<M> + ?Sized,
87 {
88     #[inline]
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>89     fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
90         (*self).dry_load(req)
91     }
92 }
93 
94 #[cfg(feature = "alloc")]
95 impl<M, P> DryDataProvider<M> for alloc::boxed::Box<P>
96 where
97     M: DataMarker,
98     P: DryDataProvider<M> + ?Sized,
99 {
100     #[inline]
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>101     fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
102         (**self).dry_load(req)
103     }
104 }
105 
106 #[cfg(feature = "alloc")]
107 impl<M, P> DryDataProvider<M> for alloc::rc::Rc<P>
108 where
109     M: DataMarker,
110     P: DryDataProvider<M> + ?Sized,
111 {
112     #[inline]
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>113     fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
114         (**self).dry_load(req)
115     }
116 }
117 
118 #[cfg(target_has_atomic = "ptr")]
119 #[cfg(feature = "alloc")]
120 impl<M, P> DryDataProvider<M> for alloc::sync::Arc<P>
121 where
122     M: DataMarker,
123     P: DryDataProvider<M> + ?Sized,
124 {
125     #[inline]
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>126     fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
127         (**self).dry_load(req)
128     }
129 }
130 
131 /// A [`DataProvider`] that can iterate over all supported [`DataIdentifierCow`]s.
132 ///
133 /// The provider is not allowed to return `Ok` for requests that were not returned by `iter_ids`,
134 /// and must not fail with a [`DataErrorKind::IdentifierNotFound`] for requests that were returned.
135 #[cfg(feature = "alloc")]
136 pub trait IterableDataProvider<M: DataMarker>: DataProvider<M> {
137     /// Returns a set of [`DataIdentifierCow`].
iter_ids(&self) -> Result<alloc::collections::BTreeSet<DataIdentifierCow>, DataError>138     fn iter_ids(&self) -> Result<alloc::collections::BTreeSet<DataIdentifierCow>, DataError>;
139 }
140 
141 /// A data provider that loads data for a specific data type.
142 ///
143 /// Unlike [`DataProvider`], there may be multiple markers corresponding to the same data type.
144 pub trait DynamicDataProvider<M>
145 where
146     M: DynamicDataMarker,
147 {
148     /// Query the provider for data, returning the result.
149     ///
150     /// Returns [`Ok`] if the request successfully loaded data. If data failed to load, returns an
151     /// Error with more information.
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>152     fn load_data(
153         &self,
154         marker: DataMarkerInfo,
155         req: DataRequest,
156     ) -> Result<DataResponse<M>, DataError>;
157 }
158 
159 impl<M, P> DynamicDataProvider<M> for &P
160 where
161     M: DynamicDataMarker,
162     P: DynamicDataProvider<M> + ?Sized,
163 {
164     #[inline]
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>165     fn load_data(
166         &self,
167         marker: DataMarkerInfo,
168         req: DataRequest,
169     ) -> Result<DataResponse<M>, DataError> {
170         (*self).load_data(marker, req)
171     }
172 }
173 
174 #[cfg(feature = "alloc")]
175 impl<M, P> DynamicDataProvider<M> for alloc::boxed::Box<P>
176 where
177     M: DynamicDataMarker,
178     P: DynamicDataProvider<M> + ?Sized,
179 {
180     #[inline]
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>181     fn load_data(
182         &self,
183         marker: DataMarkerInfo,
184         req: DataRequest,
185     ) -> Result<DataResponse<M>, DataError> {
186         (**self).load_data(marker, req)
187     }
188 }
189 
190 #[cfg(feature = "alloc")]
191 impl<M, P> DynamicDataProvider<M> for alloc::rc::Rc<P>
192 where
193     M: DynamicDataMarker,
194     P: DynamicDataProvider<M> + ?Sized,
195 {
196     #[inline]
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>197     fn load_data(
198         &self,
199         marker: DataMarkerInfo,
200         req: DataRequest,
201     ) -> Result<DataResponse<M>, DataError> {
202         (**self).load_data(marker, req)
203     }
204 }
205 
206 #[cfg(target_has_atomic = "ptr")]
207 #[cfg(feature = "alloc")]
208 impl<M, P> DynamicDataProvider<M> for alloc::sync::Arc<P>
209 where
210     M: DynamicDataMarker,
211     P: DynamicDataProvider<M> + ?Sized,
212 {
213     #[inline]
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>214     fn load_data(
215         &self,
216         marker: DataMarkerInfo,
217         req: DataRequest,
218     ) -> Result<DataResponse<M>, DataError> {
219         (**self).load_data(marker, req)
220     }
221 }
222 
223 /// A dynanmic data provider that can determine whether it can load a particular data identifier,
224 /// potentially cheaper than actually performing the load.
225 pub trait DynamicDryDataProvider<M: DynamicDataMarker>: DynamicDataProvider<M> {
226     /// This method goes through the motions of [`load_data`], but only returns the metadata.
227     ///
228     /// If `dry_load_data` returns an error, [`load_data`] must return the same error, but
229     /// not vice-versa. Concretely, [`load_data`] could return deserialization or I/O errors
230     /// that `dry_load_data` cannot predict.
231     ///
232     /// [`load_data`]: DynamicDataProvider::load_data
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>233     fn dry_load_data(
234         &self,
235         marker: DataMarkerInfo,
236         req: DataRequest,
237     ) -> Result<DataResponseMetadata, DataError>;
238 }
239 
240 impl<M, P> DynamicDryDataProvider<M> for &P
241 where
242     M: DynamicDataMarker,
243     P: DynamicDryDataProvider<M> + ?Sized,
244 {
245     #[inline]
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>246     fn dry_load_data(
247         &self,
248         marker: DataMarkerInfo,
249         req: DataRequest,
250     ) -> Result<DataResponseMetadata, DataError> {
251         (*self).dry_load_data(marker, req)
252     }
253 }
254 
255 #[cfg(feature = "alloc")]
256 impl<M, P> DynamicDryDataProvider<M> for alloc::boxed::Box<P>
257 where
258     M: DynamicDataMarker,
259     P: DynamicDryDataProvider<M> + ?Sized,
260 {
261     #[inline]
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>262     fn dry_load_data(
263         &self,
264         marker: DataMarkerInfo,
265         req: DataRequest,
266     ) -> Result<DataResponseMetadata, DataError> {
267         (**self).dry_load_data(marker, req)
268     }
269 }
270 
271 #[cfg(feature = "alloc")]
272 impl<M, P> DynamicDryDataProvider<M> for alloc::rc::Rc<P>
273 where
274     M: DynamicDataMarker,
275     P: DynamicDryDataProvider<M> + ?Sized,
276 {
277     #[inline]
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>278     fn dry_load_data(
279         &self,
280         marker: DataMarkerInfo,
281         req: DataRequest,
282     ) -> Result<DataResponseMetadata, DataError> {
283         (**self).dry_load_data(marker, req)
284     }
285 }
286 
287 #[cfg(target_has_atomic = "ptr")]
288 #[cfg(feature = "alloc")]
289 impl<M, P> DynamicDryDataProvider<M> for alloc::sync::Arc<P>
290 where
291     M: DynamicDataMarker,
292     P: DynamicDryDataProvider<M> + ?Sized,
293 {
294     #[inline]
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>295     fn dry_load_data(
296         &self,
297         marker: DataMarkerInfo,
298         req: DataRequest,
299     ) -> Result<DataResponseMetadata, DataError> {
300         (**self).dry_load_data(marker, req)
301     }
302 }
303 
304 /// A [`DynamicDataProvider`] that can iterate over all supported [`DataIdentifierCow`]s for a certain marker.
305 ///
306 /// The provider is not allowed to return `Ok` for requests that were not returned by `iter_ids`,
307 /// and must not fail with a [`DataErrorKind::IdentifierNotFound`] for requests that were returned.
308 #[cfg(feature = "alloc")]
309 pub trait IterableDynamicDataProvider<M: DynamicDataMarker>: DynamicDataProvider<M> {
310     /// Given a [`DataMarkerInfo`], returns a set of [`DataIdentifierCow`].
iter_ids_for_marker( &self, marker: DataMarkerInfo, ) -> Result<alloc::collections::BTreeSet<DataIdentifierCow>, DataError>311     fn iter_ids_for_marker(
312         &self,
313         marker: DataMarkerInfo,
314     ) -> Result<alloc::collections::BTreeSet<DataIdentifierCow>, DataError>;
315 }
316 
317 #[cfg(feature = "alloc")]
318 impl<M, P> IterableDynamicDataProvider<M> for alloc::boxed::Box<P>
319 where
320     M: DynamicDataMarker,
321     P: IterableDynamicDataProvider<M> + ?Sized,
322 {
iter_ids_for_marker( &self, marker: DataMarkerInfo, ) -> Result<alloc::collections::BTreeSet<DataIdentifierCow>, DataError>323     fn iter_ids_for_marker(
324         &self,
325         marker: DataMarkerInfo,
326     ) -> Result<alloc::collections::BTreeSet<DataIdentifierCow>, DataError> {
327         (**self).iter_ids_for_marker(marker)
328     }
329 }
330 
331 /// A data provider that loads data for a specific data type.
332 ///
333 /// Unlike [`DataProvider`], the provider is bound to a specific marker ahead of time.
334 ///
335 /// This crate provides [`DataProviderWithMarker`] which implements this trait on a single provider
336 /// with a single marker. However, this trait can also be implemented on providers that fork between
337 /// multiple markers that all return the same data type. For example, it can abstract over many
338 /// calendar systems in the datetime formatter.
339 pub trait BoundDataProvider<M>
340 where
341     M: DynamicDataMarker,
342 {
343     /// Query the provider for data, returning the result.
344     ///
345     /// Returns [`Ok`] if the request successfully loaded data. If data failed to load, returns an
346     /// Error with more information.
load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>347     fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>;
348     /// Returns the [`DataMarkerInfo`] that this provider uses for loading data.
bound_marker(&self) -> DataMarkerInfo349     fn bound_marker(&self) -> DataMarkerInfo;
350 }
351 
352 impl<M, P> BoundDataProvider<M> for &P
353 where
354     M: DynamicDataMarker,
355     P: BoundDataProvider<M> + ?Sized,
356 {
357     #[inline]
load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>358     fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
359         (*self).load_bound(req)
360     }
361     #[inline]
bound_marker(&self) -> DataMarkerInfo362     fn bound_marker(&self) -> DataMarkerInfo {
363         (*self).bound_marker()
364     }
365 }
366 
367 #[cfg(feature = "alloc")]
368 impl<M, P> BoundDataProvider<M> for alloc::boxed::Box<P>
369 where
370     M: DynamicDataMarker,
371     P: BoundDataProvider<M> + ?Sized,
372 {
373     #[inline]
load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>374     fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
375         (**self).load_bound(req)
376     }
377     #[inline]
bound_marker(&self) -> DataMarkerInfo378     fn bound_marker(&self) -> DataMarkerInfo {
379         (**self).bound_marker()
380     }
381 }
382 
383 #[cfg(feature = "alloc")]
384 impl<M, P> BoundDataProvider<M> for alloc::rc::Rc<P>
385 where
386     M: DynamicDataMarker,
387     P: BoundDataProvider<M> + ?Sized,
388 {
389     #[inline]
load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>390     fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
391         (**self).load_bound(req)
392     }
393     #[inline]
bound_marker(&self) -> DataMarkerInfo394     fn bound_marker(&self) -> DataMarkerInfo {
395         (**self).bound_marker()
396     }
397 }
398 
399 #[cfg(target_has_atomic = "ptr")]
400 #[cfg(feature = "alloc")]
401 impl<M, P> BoundDataProvider<M> for alloc::sync::Arc<P>
402 where
403     M: DynamicDataMarker,
404     P: BoundDataProvider<M> + ?Sized,
405 {
406     #[inline]
load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>407     fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
408         (**self).load_bound(req)
409     }
410     #[inline]
bound_marker(&self) -> DataMarkerInfo411     fn bound_marker(&self) -> DataMarkerInfo {
412         (**self).bound_marker()
413     }
414 }
415 
416 /// A [`DataProvider`] associated with a specific marker.
417 ///
418 /// Implements [`BoundDataProvider`].
419 #[derive(Debug)]
420 pub struct DataProviderWithMarker<M, P> {
421     inner: P,
422     _marker: PhantomData<M>,
423 }
424 
425 impl<M, P> DataProviderWithMarker<M, P>
426 where
427     M: DataMarker,
428     P: DataProvider<M>,
429 {
430     /// Creates a [`DataProviderWithMarker`] from a [`DataProvider`] with a [`DataMarker`].
new(inner: P) -> Self431     pub const fn new(inner: P) -> Self {
432         Self {
433             inner,
434             _marker: PhantomData,
435         }
436     }
437 }
438 
439 impl<M, M0, Y, P> BoundDataProvider<M0> for DataProviderWithMarker<M, P>
440 where
441     M: DataMarker<DataStruct = Y>,
442     M0: DynamicDataMarker<DataStruct = Y>,
443     Y: for<'a> Yokeable<'a>,
444     P: DataProvider<M>,
445 {
446     #[inline]
load_bound(&self, req: DataRequest) -> Result<DataResponse<M0>, DataError>447     fn load_bound(&self, req: DataRequest) -> Result<DataResponse<M0>, DataError> {
448         self.inner.load(req).map(DataResponse::cast)
449     }
450     #[inline]
bound_marker(&self) -> DataMarkerInfo451     fn bound_marker(&self) -> DataMarkerInfo {
452         M::INFO
453     }
454 }
455 
456 #[cfg(test)]
457 mod test {
458 
459     use super::*;
460     use crate::hello_world::*;
461     use alloc::borrow::Cow;
462     use alloc::string::String;
463     use core::fmt::Debug;
464     use serde::{Deserialize, Serialize};
465 
466     // This tests DataProvider borrow semantics with a dummy data provider based on a
467     // JSON string. It also exercises most of the data provider code paths.
468 
469     /// A data struct serialization-compatible with HelloWorld used for testing mismatched types
470     #[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, yoke::Yokeable)]
471     pub struct HelloAlt {
472         message: String,
473     }
474 
475     data_marker!(HelloAltMarkerV1, HelloAlt);
476 
477     #[derive(Deserialize, Debug, Clone, Default, PartialEq)]
478     struct HelloCombined<'data> {
479         #[serde(borrow)]
480         pub hello_v1: HelloWorld<'data>,
481         pub hello_alt: HelloAlt,
482     }
483 
484     /// A DataProvider that owns its data, returning an Rc-variant DataPayload.
485     /// Supports only key::HELLO_WORLD_V1. Uses `impl_dynamic_data_provider!()`.
486     #[derive(Debug)]
487     struct DataWarehouse {
488         hello_v1: HelloWorld<'static>,
489         hello_alt: HelloAlt,
490     }
491 
492     impl DataProvider<HelloWorldV1> for DataWarehouse {
load(&self, _: DataRequest) -> Result<DataResponse<HelloWorldV1>, DataError>493         fn load(&self, _: DataRequest) -> Result<DataResponse<HelloWorldV1>, DataError> {
494             Ok(DataResponse {
495                 metadata: DataResponseMetadata::default(),
496                 payload: DataPayload::from_owned(self.hello_v1.clone()),
497             })
498         }
499     }
500 
501     /// A DataProvider that supports both key::HELLO_WORLD_V1 and HELLO_ALT.
502     #[derive(Debug)]
503     struct DataProvider2 {
504         data: DataWarehouse,
505     }
506 
507     impl From<DataWarehouse> for DataProvider2 {
from(warehouse: DataWarehouse) -> Self508         fn from(warehouse: DataWarehouse) -> Self {
509             DataProvider2 { data: warehouse }
510         }
511     }
512 
513     impl DataProvider<HelloWorldV1> for DataProvider2 {
load(&self, _: DataRequest) -> Result<DataResponse<HelloWorldV1>, DataError>514         fn load(&self, _: DataRequest) -> Result<DataResponse<HelloWorldV1>, DataError> {
515             Ok(DataResponse {
516                 metadata: DataResponseMetadata::default(),
517                 payload: DataPayload::from_owned(self.data.hello_v1.clone()),
518             })
519         }
520     }
521 
522     impl DataProvider<HelloAltMarkerV1> for DataProvider2 {
load(&self, _: DataRequest) -> Result<DataResponse<HelloAltMarkerV1>, DataError>523         fn load(&self, _: DataRequest) -> Result<DataResponse<HelloAltMarkerV1>, DataError> {
524             Ok(DataResponse {
525                 metadata: DataResponseMetadata::default(),
526                 payload: DataPayload::from_owned(self.data.hello_alt.clone()),
527             })
528         }
529     }
530 
531     const DATA: &str = r#"{
532         "hello_v1": {
533             "message": "Hello "
534         },
535         "hello_alt": {
536             "message": "Hello Alt"
537         }
538     }"#;
539 
get_warehouse(data: &'static str) -> DataWarehouse540     fn get_warehouse(data: &'static str) -> DataWarehouse {
541         let data: HelloCombined = serde_json::from_str(data).expect("Well-formed data");
542         DataWarehouse {
543             hello_v1: data.hello_v1,
544             hello_alt: data.hello_alt,
545         }
546     }
547 
get_payload_v1<P: DataProvider<HelloWorldV1> + ?Sized>( provider: &P, ) -> Result<DataPayload<HelloWorldV1>, DataError>548     fn get_payload_v1<P: DataProvider<HelloWorldV1> + ?Sized>(
549         provider: &P,
550     ) -> Result<DataPayload<HelloWorldV1>, DataError> {
551         provider.load(Default::default()).map(|r| r.payload)
552     }
553 
get_payload_alt<P: DataProvider<HelloAltMarkerV1> + ?Sized>( provider: &P, ) -> Result<DataPayload<HelloAltMarkerV1>, DataError>554     fn get_payload_alt<P: DataProvider<HelloAltMarkerV1> + ?Sized>(
555         provider: &P,
556     ) -> Result<DataPayload<HelloAltMarkerV1>, DataError> {
557         provider.load(Default::default()).map(|r| r.payload)
558     }
559 
560     #[test]
test_warehouse_owned()561     fn test_warehouse_owned() {
562         let warehouse = get_warehouse(DATA);
563         let hello_data = get_payload_v1(&warehouse).unwrap();
564         assert!(matches!(
565             hello_data.get(),
566             HelloWorld {
567                 message: Cow::Borrowed(_),
568             }
569         ));
570     }
571 
572     #[test]
test_warehouse_owned_dyn_generic()573     fn test_warehouse_owned_dyn_generic() {
574         let warehouse = get_warehouse(DATA);
575         let hello_data = get_payload_v1(&warehouse as &dyn DataProvider<HelloWorldV1>).unwrap();
576         assert!(matches!(
577             hello_data.get(),
578             HelloWorld {
579                 message: Cow::Borrowed(_),
580             }
581         ));
582     }
583 
584     #[test]
test_provider2()585     fn test_provider2() {
586         let warehouse = get_warehouse(DATA);
587         let provider = DataProvider2::from(warehouse);
588         let hello_data = get_payload_v1(&provider).unwrap();
589         assert!(matches!(
590             hello_data.get(),
591             HelloWorld {
592                 message: Cow::Borrowed(_),
593             }
594         ));
595     }
596 
597     #[test]
test_provider2_dyn_generic()598     fn test_provider2_dyn_generic() {
599         let warehouse = get_warehouse(DATA);
600         let provider = DataProvider2::from(warehouse);
601         let hello_data = get_payload_v1(&provider as &dyn DataProvider<HelloWorldV1>).unwrap();
602         assert!(matches!(
603             hello_data.get(),
604             HelloWorld {
605                 message: Cow::Borrowed(_),
606             }
607         ));
608     }
609 
610     #[test]
test_provider2_dyn_generic_alt()611     fn test_provider2_dyn_generic_alt() {
612         let warehouse = get_warehouse(DATA);
613         let provider = DataProvider2::from(warehouse);
614         let hello_data = get_payload_alt(&provider as &dyn DataProvider<HelloAltMarkerV1>).unwrap();
615         assert!(matches!(hello_data.get(), HelloAlt { .. }));
616     }
617 
check_v1_v2<P>(d: &P) where P: DataProvider<HelloWorldV1> + DataProvider<HelloAltMarkerV1> + ?Sized,618     fn check_v1_v2<P>(d: &P)
619     where
620         P: DataProvider<HelloWorldV1> + DataProvider<HelloAltMarkerV1> + ?Sized,
621     {
622         let v1: DataPayload<HelloWorldV1> = d.load(Default::default()).unwrap().payload;
623         let v2: DataPayload<HelloAltMarkerV1> = d.load(Default::default()).unwrap().payload;
624         if v1.get().message == v2.get().message {
625             panic!()
626         }
627     }
628 
629     #[test]
test_v1_v2_generic()630     fn test_v1_v2_generic() {
631         let warehouse = get_warehouse(DATA);
632         let provider = DataProvider2::from(warehouse);
633         check_v1_v2(&provider);
634     }
635 }
636