| 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 | //! Traits for data providers that produce opaque buffers. |
| 6 | |
| 7 | use crate::prelude::*; |
| 8 | |
| 9 | /// [`DataMarker`] for raw buffers. Returned by [`BufferProvider`]. |
| 10 | /// |
| 11 | /// The data is expected to be deserialized before it can be used; see |
| 12 | /// [`DataPayload::into_deserialized`]. |
| 13 | #[allow (clippy::exhaustive_structs)] // marker type |
| 14 | #[derive (Debug)] |
| 15 | pub struct BufferMarker; |
| 16 | |
| 17 | impl DataMarker for BufferMarker { |
| 18 | type Yokeable = &'static [u8]; |
| 19 | } |
| 20 | |
| 21 | /// A data provider that returns opaque bytes. |
| 22 | /// |
| 23 | /// Generally, these bytes are expected to be deserializable with Serde. To get an object |
| 24 | /// implementing [`DataProvider`] via Serde, use [`as_deserializing()`]. |
| 25 | /// |
| 26 | /// Passing a `BufferProvider` to a `*_with_buffer_provider` constructor requires enabling |
| 27 | /// the deserialization Cargo feature for the expected format(s): |
| 28 | /// - `deserialize_json` |
| 29 | /// - `deserialize_postcard_1` |
| 30 | /// - `deserialize_bincode_1` |
| 31 | /// |
| 32 | /// Along with [`DataProvider`], this is one of the two foundational traits in this crate. |
| 33 | /// |
| 34 | /// [`BufferProvider`] can be made into a trait object. It is used over FFI. |
| 35 | /// |
| 36 | /// # Examples |
| 37 | /// |
| 38 | /// ``` |
| 39 | /// # #[cfg (feature = "deserialize_json" )] { |
| 40 | /// use icu_locid::langid; |
| 41 | /// use icu_provider::hello_world::*; |
| 42 | /// use icu_provider::prelude::*; |
| 43 | /// use std::borrow::Cow; |
| 44 | /// |
| 45 | /// let buffer_provider = HelloWorldProvider.into_json_provider(); |
| 46 | /// |
| 47 | /// let req = DataRequest { |
| 48 | /// locale: &langid!("de" ).into(), |
| 49 | /// metadata: Default::default(), |
| 50 | /// }; |
| 51 | /// |
| 52 | /// // Deserializing manually |
| 53 | /// assert_eq!( |
| 54 | /// serde_json::from_slice::<HelloWorldV1>( |
| 55 | /// buffer_provider |
| 56 | /// .load_buffer(HelloWorldV1Marker::KEY, req) |
| 57 | /// .expect("load should succeed" ) |
| 58 | /// .take_payload() |
| 59 | /// .unwrap() |
| 60 | /// .get() |
| 61 | /// ) |
| 62 | /// .expect("should deserialize" ), |
| 63 | /// HelloWorldV1 { |
| 64 | /// message: Cow::Borrowed("Hallo Welt" ), |
| 65 | /// }, |
| 66 | /// ); |
| 67 | /// |
| 68 | /// // Deserialize automatically |
| 69 | /// let deserializing_provider: &dyn DataProvider<HelloWorldV1Marker> = |
| 70 | /// &buffer_provider.as_deserializing(); |
| 71 | /// |
| 72 | /// assert_eq!( |
| 73 | /// deserializing_provider |
| 74 | /// .load(req) |
| 75 | /// .expect("load should succeed" ) |
| 76 | /// .take_payload() |
| 77 | /// .unwrap() |
| 78 | /// .get(), |
| 79 | /// &HelloWorldV1 { |
| 80 | /// message: Cow::Borrowed("Hallo Welt" ), |
| 81 | /// }, |
| 82 | /// ); |
| 83 | /// # } |
| 84 | /// ``` |
| 85 | /// |
| 86 | /// [`as_deserializing()`]: AsDeserializingBufferProvider::as_deserializing |
| 87 | pub trait BufferProvider { |
| 88 | /// Loads a [`DataPayload`]`<`[`BufferMarker`]`>` according to the key and request. |
| 89 | fn load_buffer( |
| 90 | &self, |
| 91 | key: DataKey, |
| 92 | req: DataRequest, |
| 93 | ) -> Result<DataResponse<BufferMarker>, DataError>; |
| 94 | } |
| 95 | |
| 96 | impl<'a, T: BufferProvider + ?Sized> BufferProvider for &'a T { |
| 97 | #[inline ] |
| 98 | fn load_buffer( |
| 99 | &self, |
| 100 | key: DataKey, |
| 101 | req: DataRequest, |
| 102 | ) -> Result<DataResponse<BufferMarker>, DataError> { |
| 103 | (**self).load_buffer(key, req) |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | impl<T: BufferProvider + ?Sized> BufferProvider for alloc::boxed::Box<T> { |
| 108 | #[inline ] |
| 109 | fn load_buffer( |
| 110 | &self, |
| 111 | key: DataKey, |
| 112 | req: DataRequest, |
| 113 | ) -> Result<DataResponse<BufferMarker>, DataError> { |
| 114 | (**self).load_buffer(key, req) |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | impl<T: BufferProvider + ?Sized> BufferProvider for alloc::rc::Rc<T> { |
| 119 | #[inline ] |
| 120 | fn load_buffer( |
| 121 | &self, |
| 122 | key: DataKey, |
| 123 | req: DataRequest, |
| 124 | ) -> Result<DataResponse<BufferMarker>, DataError> { |
| 125 | (**self).load_buffer(key, req) |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | #[cfg (target_has_atomic = "ptr" )] |
| 130 | impl<T: BufferProvider + ?Sized> BufferProvider for alloc::sync::Arc<T> { |
| 131 | #[inline ] |
| 132 | fn load_buffer( |
| 133 | &self, |
| 134 | key: DataKey, |
| 135 | req: DataRequest, |
| 136 | ) -> Result<DataResponse<BufferMarker>, DataError> { |
| 137 | (**self).load_buffer(key, req) |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | /// An enum expressing all Serde formats known to ICU4X. |
| 142 | #[derive (Debug, PartialEq, Eq, Hash, Copy, Clone)] |
| 143 | #[cfg_attr (feature = "serde" , derive(serde::Serialize, serde::Deserialize))] |
| 144 | #[non_exhaustive ] |
| 145 | pub enum BufferFormat { |
| 146 | /// Serialize using JavaScript Object Notation (JSON). |
| 147 | Json, |
| 148 | /// Serialize using Bincode version 1. |
| 149 | Bincode1, |
| 150 | /// Serialize using Postcard version 1. |
| 151 | Postcard1, |
| 152 | } |
| 153 | |
| 154 | impl BufferFormat { |
| 155 | /// Returns an error if the buffer format is not enabled. |
| 156 | pub fn check_available(&self) -> Result<(), DataError> { |
| 157 | match self { |
| 158 | #[cfg (feature = "deserialize_json" )] |
| 159 | BufferFormat::Json => Ok(()), |
| 160 | |
| 161 | #[cfg (feature = "deserialize_bincode_1" )] |
| 162 | BufferFormat::Bincode1 => Ok(()), |
| 163 | |
| 164 | #[cfg (feature = "deserialize_postcard_1" )] |
| 165 | BufferFormat::Postcard1 => Ok(()), |
| 166 | |
| 167 | // Allowed for cases in which all features are enabled |
| 168 | #[allow (unreachable_patterns)] |
| 169 | _ => Err(DataErrorKind::UnavailableBufferFormat(*self).into_error()), |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | |