1extern crate alloc;
6
7use alloc::collections::{BTreeMap, BTreeSet};
8use icu_provider::prelude::*;
9
10macro_rules! cb {
11 ($($marker_ty:ty:$marker:ident,)+ #[unstable] $($emarker_ty:ty:$emarker:ident,)+) => {
12 pub fn markers_for_bin(bytes: &[u8]) -> Result<BTreeSet<DataMarkerInfo>, DataError> {
36 use crate as icu;
37 let lookup =
38 alloc::vec![
39 (icu_provider::hello_world::HelloWorldV1::INFO.id.hashed().to_bytes(), Ok(icu_provider::hello_world::HelloWorldV1::INFO)),
40 $(
41 (<$marker_ty>::INFO.id.hashed().to_bytes(), Ok(<$marker_ty>::INFO)),
42 )+
43 $(
44 #[cfg(feature = "unstable")]
45 (<$emarker_ty>::INFO.id.hashed().to_bytes(), Ok(<$emarker_ty>::INFO)),
46 #[cfg(not(feature = "unstable"))]
47 (icu_provider::marker::DataMarkerId::from_name(stringify!($emarker)).unwrap().hashed().to_bytes(), Err(stringify!($emarker))),
48 )+
49
50 ]
51 .into_iter()
52 .collect::<BTreeMap<[u8; 4],Result<DataMarkerInfo, &'static str>>>();
53
54 use memchr::memmem::*;
55
56 find_iter(bytes, icu_provider::marker::DataMarkerIdHash::LEADING_TAG)
57 .map(|tag_position| tag_position + icu_provider::marker::DataMarkerIdHash::LEADING_TAG.len())
58 .filter_map(|marker_start| bytes.get(marker_start..marker_start+4))
59 .filter_map(|p| {
60 match lookup.get(p) {
61 Some(Ok(marker)) => Some(Ok(*marker)),
62 Some(Err(p)) => Some(Err(DataError::custom("This marker requires the `unstable` Cargo feature").with_display_context(p))),
63 None => None,
64 }
65 })
66 .collect::<Result<_, _>>()
67 }
68 }
69}
70icu_provider_registry::registry!(cb);
71
72#[test]
73fn test_markers_for_bin() {
74 assert_eq!(
75 markers_for_bin(include_bytes!("../tests/data/tutorial_buffer.wasm")).unwrap(),
76 [
77 crate::datetime::provider::names::DayPeriodNamesV1::INFO,
78 crate::datetime::provider::names::DatetimeNamesMonthGregorianV1::INFO,
79 crate::datetime::provider::names::DatetimeNamesYearGregorianV1::INFO,
80 crate::datetime::provider::semantic_skeletons::DatetimePatternsGlueV1::INFO,
81 crate::datetime::provider::semantic_skeletons::DatetimePatternsDateGregorianV1::INFO,
82 crate::datetime::provider::semantic_skeletons::DatetimePatternsTimeV1::INFO,
83 crate::decimal::provider::DecimalSymbolsV1::INFO,
84 crate::decimal::provider::DecimalDigitsV1::INFO,
85 ]
86 .into_iter()
87 .collect(),
88 );
89}