use crate::data::store::LocaleProfile;
use bistun_core::error::LmsError;
use bistun_core::manifest::{CapabilityManifest, TraitValue};
use bistun_core::traits::TraitKey;
pub fn apply_rendering_traits(
manifest: &mut CapabilityManifest,
profile: &LocaleProfile,
raw_tag: &str,
) -> Result<(), LmsError> {
manifest.traits.insert(TraitKey::PrimaryDirection, TraitValue::Direction(profile.direction));
manifest.traits.insert(TraitKey::HasBidiElements, TraitValue::Boolean(profile.has_bidi));
manifest
.traits
.insert(TraitKey::RequiresShaping, TraitValue::Boolean(profile.requires_shaping));
if let Some(u_ext_start) = raw_tag.find("-u-") {
let extension_subtag = &raw_tag[u_ext_start + 3..];
let mut iter = extension_subtag.split('-');
while let Some(part) = iter.next() {
if part.len() == 1 {
break;
}
match part {
"nu" => {
if let Some(val) = iter.next() {
manifest
.traits
.insert(TraitKey::NumberingSystem, TraitValue::String(val.to_string()));
}
}
"ca" => {
if let Some(val) = iter.next() {
manifest
.traits
.insert(TraitKey::Calendar, TraitValue::String(val.to_string()));
}
}
_ => continue,
}
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use bistun_core::traits::{Direction, MorphType, NormType, SegType, TransType};
fn create_mock_profile(
direction: Direction,
has_bidi: bool,
requires_shaping: bool,
) -> LocaleProfile {
LocaleProfile {
id: "test".to_string(),
morph: MorphType::ISOLATING,
base_seg: SegType::SPACE,
alt_seg: None,
direction,
has_bidi,
requires_shaping,
plurals: vec!["other".to_string()],
unicode_blocks: vec![],
normalization: NormType::NFC,
transliteration: TransType::NONE,
required_resource: None,
}
}
#[test]
fn test_apply_unicode_overrides() {
let mut manifest = CapabilityManifest::new("en-US".to_string());
let profile = create_mock_profile(Direction::LTR, false, false);
assert!(
apply_rendering_traits(&mut manifest, &profile, "en-US-u-nu-latn-ca-gregory").is_ok()
);
assert_eq!(
manifest.traits.get(&TraitKey::NumberingSystem),
Some(&TraitValue::String("latn".to_string()))
);
assert_eq!(
manifest.traits.get(&TraitKey::Calendar),
Some(&TraitValue::String("gregory".to_string()))
);
}
#[test]
fn test_apply_rtl_bidi_traits() {
let mut manifest = CapabilityManifest::new("ar-EG".to_string());
let profile = create_mock_profile(Direction::RTL, true, true);
assert!(apply_rendering_traits(&mut manifest, &profile, "ar-EG").is_ok());
let dir = manifest.traits.get(&TraitKey::PrimaryDirection);
assert_eq!(dir, Some(&TraitValue::Direction(Direction::RTL)));
let bidi = manifest.traits.get(&TraitKey::HasBidiElements);
assert_eq!(bidi, Some(&TraitValue::Boolean(true)));
}
#[test]
fn test_apply_ttb_traits() {
let mut manifest = CapabilityManifest::new("zh-Hant".to_string());
let profile = create_mock_profile(Direction::TTB, false, false);
assert!(apply_rendering_traits(&mut manifest, &profile, "zh-Hant").is_ok());
let dir = manifest.traits.get(&TraitKey::PrimaryDirection);
assert_eq!(dir, Some(&TraitValue::Direction(Direction::TTB)));
}
}