icu_provider_source/units/
trie.rsuse std::collections::{BTreeMap, HashSet};
use crate::cldr_serde;
use crate::cldr_serde::units::info::ConvertUnit;
use crate::SourceDataProvider;
use icu::experimental::measure::provider::trie::{UnitsTrieV1, UnitsTrieV1Marker};
use icu_provider::prelude::*;
use zerotrie::ZeroTrieSimpleAscii;
impl DataProvider<UnitsTrieV1Marker> for SourceDataProvider {
fn load(&self, _req: DataRequest) -> Result<DataResponse<UnitsTrieV1Marker>, DataError> {
self.check_req::<UnitsTrieV1Marker>(_req)?;
let units_data: &cldr_serde::units::info::Resource = self
.cldr()?
.core()
.read_and_parse("supplemental/units.json")?;
let convert_units = &units_data.supplemental.convert_units.convert_units;
let mut trie_map = BTreeMap::<Vec<u8>, usize>::new();
let mut convert_units_vec = Vec::<&ConvertUnit>::new();
for (unit_name, convert_unit) in convert_units {
let convert_unit_index = convert_units_vec.len();
convert_units_vec.push(convert_unit);
trie_map.insert(unit_name.as_bytes().to_vec(), convert_unit_index);
}
let units_conversion_trie = ZeroTrieSimpleAscii::try_from(&trie_map).map_err(|e| {
DataError::custom("Could not create ZeroTrie from units.json data")
.with_display_context(&e)
})?;
let result = UnitsTrieV1 {
trie: units_conversion_trie.convert_store(),
};
Ok(DataResponse {
metadata: Default::default(),
payload: DataPayload::from_owned(result),
})
}
}
impl crate::IterableDataProviderCached<UnitsTrieV1Marker> for SourceDataProvider {
fn iter_ids_cached(&self) -> Result<HashSet<DataIdentifierCow<'static>>, DataError> {
Ok(HashSet::from_iter([Default::default()]))
}
}
#[test]
fn test_basic() {
use icu::experimental::units::provider::UnitsInfoV1Marker;
use icu::locale::langid;
use icu_provider::prelude::*;
let provider = SourceDataProvider::new_testing();
let und_trie: DataResponse<UnitsTrieV1Marker> = provider
.load(DataRequest {
id: DataIdentifierCow::from_locale(langid!("und").into()).as_borrowed(),
..Default::default()
})
.unwrap();
let units_info = und_trie.payload.get().to_owned();
let trie = &units_info.trie;
let und_info: DataResponse<UnitsInfoV1Marker> = provider
.load(DataRequest {
id: DataIdentifierCow::from_locale(langid!("und").into()).as_borrowed(),
..Default::default()
})
.unwrap();
let units_info = und_info.payload.get().to_owned();
let meter_id = trie.get("meter").unwrap();
let foot_id = trie.get("foot").unwrap();
let convert_infos = &units_info.convert_infos[meter_id];
let basic_units = &convert_infos.basic_units();
assert_eq!(basic_units.first().unwrap().unit_id, meter_id as u16);
let convert_infos = &units_info.convert_infos[foot_id];
let basic_units = &convert_infos.basic_units();
assert_eq!(basic_units.first().unwrap().unit_id, meter_id as u16);
}