extern crate alloc;
use alloc::collections::{BTreeMap, BTreeSet};
use icu_provider::prelude::*;
macro_rules! cb {
($($marker_ty:ty:$marker:ident,)+ #[unstable] $($emarker_ty:ty:$emarker:ident,)+) => {
pub fn markers_for_bin(bytes: &[u8]) -> Result<BTreeSet<DataMarkerInfo>, DataError> {
use crate as icu;
let lookup =
alloc::vec![
(icu_provider::hello_world::HelloWorldV1::INFO.id.hashed().to_bytes(), Ok(icu_provider::hello_world::HelloWorldV1::INFO)),
$(
(<$marker_ty>::INFO.id.hashed().to_bytes(), Ok(<$marker_ty>::INFO)),
)+
$(
#[cfg(feature = "unstable")]
(<$emarker_ty>::INFO.id.hashed().to_bytes(), Ok(<$emarker_ty>::INFO)),
#[cfg(not(feature = "unstable"))]
(icu_provider::marker::DataMarkerId::from_name(stringify!($emarker)).unwrap().hashed().to_bytes(), Err(stringify!($emarker))),
)+
]
.into_iter()
.collect::<BTreeMap<[u8; 4],Result<DataMarkerInfo, &'static str>>>();
use memchr::memmem::*;
find_iter(bytes, icu_provider::marker::DataMarkerIdHash::LEADING_TAG)
.map(|tag_position| tag_position + icu_provider::marker::DataMarkerIdHash::LEADING_TAG.len())
.filter_map(|marker_start| bytes.get(marker_start..marker_start+4))
.filter_map(|p| {
match lookup.get(p) {
Some(Ok(marker)) => Some(Ok(*marker)),
Some(Err(p)) => Some(Err(DataError::custom("This marker requires the `unstable` Cargo feature").with_display_context(p))),
None => None,
}
})
.collect::<Result<_, _>>()
}
}
}
icu_provider_registry::registry!(cb);
#[test]
fn test_markers_for_bin() {
assert_eq!(
markers_for_bin(include_bytes!("../tests/data/tutorial_buffer.wasm")).unwrap(),
[
crate::datetime::provider::names::DayPeriodNamesV1::INFO,
crate::datetime::provider::names::DatetimeNamesMonthGregorianV1::INFO,
crate::datetime::provider::names::DatetimeNamesYearGregorianV1::INFO,
crate::datetime::provider::semantic_skeletons::DatetimePatternsGlueV1::INFO,
crate::datetime::provider::semantic_skeletons::DatetimePatternsDateGregorianV1::INFO,
crate::datetime::provider::semantic_skeletons::DatetimePatternsTimeV1::INFO,
crate::decimal::provider::DecimalSymbolsV1::INFO,
crate::decimal::provider::DecimalDigitsV1::INFO,
]
.into_iter()
.collect(),
);
}