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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
// 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 ).
//! Traits for data providers that produce opaque buffers.
use crate::prelude::*;
#[cfg(feature = "serde")]
mod serde;
#[cfg(feature = "serde")]
pub use self::serde::*;
/// [`DynamicDataMarker`] for raw buffers. Returned by [`BufferProvider`].
///
/// The data is expected to be deserialized before it can be used; see
/// [`DataPayload::into_deserialized`].
#[allow(clippy::exhaustive_structs)] // marker type
#[derive(Debug)]
pub struct BufferMarker;
impl DynamicDataMarker for BufferMarker {
type DataStruct = &'static [u8];
}
/// A data provider that returns opaque bytes.
///
/// Generally, these bytes are expected to be deserializable with Serde. To get an object
/// implementing [`DataProvider`] via Serde, use [`as_deserializing()`].
///
/// Passing a `BufferProvider` to a `*_with_buffer_provider` constructor requires enabling
/// the deserialization Cargo feature for the expected format(s):
/// - `deserialize_json`
/// - `deserialize_postcard_1`
/// - `deserialize_bincode_1`
///
/// Along with [`DataProvider`], this is one of the two foundational traits in this crate.
///
/// [`BufferProvider`] can be made into a trait object. It is used over FFI.
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "deserialize_json")] {
/// use icu_locale_core::langid;
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
/// use std::borrow::Cow;
///
/// let buffer_provider = HelloWorldProvider.into_json_provider();
///
/// // Deserializing manually
/// assert_eq!(
/// serde_json::from_slice::<HelloWorldV1>(
/// buffer_provider
/// .load_data(HelloWorldV1Marker::INFO, DataRequest {
/// id: DataIdentifierBorrowed::for_locale(&langid!("de").into()),
/// ..Default::default()
/// })
/// .expect("load should succeed")
/// .payload
/// .get()
/// )
/// .expect("should deserialize"),
/// HelloWorldV1 {
/// message: Cow::Borrowed("Hallo Welt"),
/// },
/// );
///
/// // Deserialize automatically
/// let deserializing_provider: &dyn DataProvider<HelloWorldV1Marker> =
/// &buffer_provider.as_deserializing();
///
/// assert_eq!(
/// deserializing_provider
/// .load(DataRequest {
/// id: DataIdentifierBorrowed::for_locale(&langid!("de").into()),
/// ..Default::default()
/// })
/// .expect("load should succeed")
/// .payload
/// .get(),
/// &HelloWorldV1 {
/// message: Cow::Borrowed("Hallo Welt"),
/// },
/// );
/// # }
/// ```
///
/// [`as_deserializing()`]: AsDeserializingBufferProvider::as_deserializing
pub trait BufferProvider: DynamicDataProvider<BufferMarker> {}
impl<P: DynamicDataProvider<BufferMarker> + ?Sized> BufferProvider for P {}
/// An enum expressing all Serde formats known to ICU4X.
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[non_exhaustive]
pub enum BufferFormat {
/// Serialize using JavaScript Object Notation (JSON), using the [`serde_json`] crate.
Json,
/// Serialize using the [`bincode`] crate, version 1.
Bincode1,
/// Serialize using the [`postcard`] crate, version 1.
Postcard1,
}
impl BufferFormat {
/// Returns an error if the buffer format is not enabled.
pub fn check_available(&self) -> Result<(), DataError> {
match self {
#[cfg(feature = "deserialize_json")]
BufferFormat::Json => Ok(()),
#[cfg(not(feature = "deserialize_json"))]
BufferFormat::Json => Err(DataErrorKind::Deserialize.with_str_context("deserializing `BufferFormat::Json` requires the `deserialize_json` Cargo feature")),
#[cfg(feature = "deserialize_bincode_1")]
BufferFormat::Bincode1 => Ok(()),
#[cfg(not(feature = "deserialize_bincode_1"))]
BufferFormat::Bincode1 => Err(DataErrorKind::Deserialize.with_str_context("deserializing `BufferFormat::Bincode1` requires the `deserialize_bincode_1` Cargo feature")),
#[cfg(feature = "deserialize_postcard_1")]
BufferFormat::Postcard1 => Ok(()),
#[cfg(not(feature = "deserialize_postcard_1"))]
BufferFormat::Postcard1 => Err(DataErrorKind::Deserialize.with_str_context("deserializing `BufferFormat::Postcard1` requires the `deserialize_postcard_1` Cargo feature")),
}
}
}