#[cfg(feature = "buffer_provider")]
use icu_provider::prelude::*;
#[cfg(feature = "buffer_provider")]
pub enum DataProviderInner {
Destroyed,
Buffer(alloc::boxed::Box<dyn BufferProvider + 'static>),
}
#[diplomat::bridge]
#[diplomat::abi_rename = "icu4x_{0}_mv1"]
#[diplomat::attr(auto, namespace = "icu4x")]
#[cfg(feature = "buffer_provider")]
pub mod ffi {
use alloc::boxed::Box;
use super::DataProviderInner;
use crate::errors::ffi::DataError;
#[diplomat::opaque]
#[diplomat::rust_link(icu_provider, Mod)]
pub struct DataProvider(pub DataProviderInner);
fn convert_buffer_provider<D: icu_provider::buf::BufferProvider + 'static>(
x: D,
) -> DataProvider {
DataProvider(super::DataProviderInner::Buffer(Box::new(x)))
}
impl DataProvider {
#[allow(unused)]
pub(crate) fn call_constructor<F, Ret>(
&self,
ctor: F,
) -> Result<Ret, icu_provider::DataError>
where
F: FnOnce(
&(dyn icu_provider::buf::BufferProvider + 'static),
) -> Result<Ret, icu_provider::DataError>,
{
match &self.0 {
DataProviderInner::Destroyed => Err(icu_provider::DataError::custom(
"This provider has been destroyed",
))?,
DataProviderInner::Buffer(ref buffer_provider) => ctor(buffer_provider),
}
}
#[allow(unused)]
#[cfg(any(feature = "datetime", feature = "decimal", feature = "experimental"))]
pub(crate) fn call_constructor_custom_err<F, Ret, Err>(&self, ctor: F) -> Result<Ret, Err>
where
Err: From<icu_provider::DataError>,
F: FnOnce(&(dyn icu_provider::buf::BufferProvider + 'static)) -> Result<Ret, Err>,
{
match &self.0 {
DataProviderInner::Destroyed => Err(icu_provider::DataError::custom(
"This provider has been destroyed",
))?,
DataProviderInner::Buffer(ref buffer_provider) => ctor(buffer_provider),
}
}
#[diplomat::rust_link(icu_provider_fs::FsDataProvider, Struct)]
#[cfg(all(
feature = "provider_fs",
not(any(target_arch = "wasm32", target_os = "none"))
))]
#[diplomat::attr(any(dart, js), disable)]
#[diplomat::attr(supports = fallible_constructors, named_constructor)]
pub fn from_fs(path: &DiplomatStr) -> Result<Box<DataProvider>, DataError> {
Ok(Box::new(convert_buffer_provider(
icu_provider_fs::FsDataProvider::try_new(
core::str::from_utf8(path)
.map_err(|_| DataError::Io)?
.into(),
)?,
)))
}
#[diplomat::rust_link(icu_provider_blob::BlobDataProvider, Struct)]
#[diplomat::attr(supports = fallible_constructors, named_constructor)]
#[diplomat::attr(not(supports = static_slices), disable)]
pub fn from_byte_slice(
blob: &'static [DiplomatByte],
) -> Result<Box<DataProvider>, DataError> {
Ok(Box::new(convert_buffer_provider(
icu_provider_blob::BlobDataProvider::try_new_from_static_blob(blob)?,
)))
}
#[diplomat::rust_link(icu_provider_adapters::fork::ForkByMarkerProvider, Typedef)]
#[diplomat::rust_link(
icu_provider_adapters::fork::predicates::MarkerNotFoundPredicate,
Struct,
hidden
)]
pub fn fork_by_key(&mut self, other: &mut DataProvider) -> Result<(), DataError> {
#[allow(unused_imports)]
use DataProviderInner::*;
*self = match (
core::mem::replace(&mut self.0, Destroyed),
core::mem::replace(&mut other.0, Destroyed),
) {
(Destroyed, _) | (_, Destroyed) => Err(icu_provider::DataError::custom(
"This provider has been destroyed",
))?,
(Buffer(a), Buffer(b)) => convert_buffer_provider(
icu_provider_adapters::fork::ForkByMarkerProvider::new(a, b),
),
};
Ok(())
}
#[diplomat::rust_link(
icu_provider_adapters::fork::predicates::IdentifierNotFoundPredicate,
Struct
)]
pub fn fork_by_locale(&mut self, other: &mut DataProvider) -> Result<(), DataError> {
#[allow(unused_imports)]
use DataProviderInner::*;
*self = match (
core::mem::replace(&mut self.0, Destroyed),
core::mem::replace(&mut other.0, Destroyed),
) {
(Destroyed, _) | (_, Destroyed) => Err(icu_provider::DataError::custom(
"This provider has been destroyed",
))?,
(Buffer(a), Buffer(b)) => convert_buffer_provider(
icu_provider_adapters::fork::ForkByErrorProvider::new_with_predicate(
a,
b,
icu_provider_adapters::fork::predicates::IdentifierNotFoundPredicate,
),
),
};
Ok(())
}
#[diplomat::rust_link(
icu_provider_adapters::fallback::LocaleFallbackProvider::new,
FnInStruct
)]
#[diplomat::rust_link(
icu_provider_adapters::fallback::LocaleFallbackProvider,
Struct,
compact
)]
#[allow(unused_variables)] #[cfg(feature = "locale")]
pub fn enable_locale_fallback_with(
&mut self,
fallbacker: &crate::fallbacker::ffi::LocaleFallbacker,
) -> Result<(), DataError> {
use DataProviderInner::*;
*self = match core::mem::replace(&mut self.0, Destroyed) {
Destroyed => Err(icu_provider::DataError::custom(
"This provider has been destroyed",
))?,
Buffer(inner) => convert_buffer_provider(
icu_provider_adapters::fallback::LocaleFallbackProvider::new(
inner,
fallbacker.0.clone(),
),
),
};
Ok(())
}
}
}
#[cfg(feature = "buffer_provider")]
macro_rules! load {
() => {
fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
use DataProviderInner::*;
match self {
Destroyed => Err(DataError::custom("This provider has been destroyed"))?,
#[cfg(feature = "buffer_provider")]
Buffer(buffer_provider) => buffer_provider.as_deserializing().load(req),
}
}
};
}
#[cfg(feature = "buffer_provider")]
impl<M> DataProvider<M> for DataProviderInner
where
M: DataMarker,
for<'de> yoke::trait_hack::YokeTraitHack<<M::DataStruct as yoke::Yokeable<'de>>::Output>:
serde::Deserialize<'de>,
{
load!();
}
#[macro_export]
macro_rules! call_constructor_unstable {
($unstable:path, $provider:expr $(, $args:expr)* $(,)?) => {
match &$provider.0 {
$crate::provider::DataProviderInner::Destroyed => Err(icu_provider::DataError::custom(
"This provider has been destroyed",
))?,
$crate::provider::DataProviderInner::Buffer(buffer_provider) => $unstable(&icu_provider::buf::AsDeserializingBufferProvider::as_deserializing(buffer_provider), $($args,)*),
}
};
}