diff options
Diffstat (limited to 'third_party/rust/unicode-bidi/src/implicit.rs')
-rw-r--r-- | third_party/rust/unicode-bidi/src/implicit.rs | 93 |
1 files changed, 57 insertions, 36 deletions
diff --git a/third_party/rust/unicode-bidi/src/implicit.rs b/third_party/rust/unicode-bidi/src/implicit.rs index 0311053c0a..334afec049 100644 --- a/third_party/rust/unicode-bidi/src/implicit.rs +++ b/third_party/rust/unicode-bidi/src/implicit.rs @@ -9,8 +9,11 @@ //! 3.3.4 - 3.3.6. Resolve implicit levels and types. +#[cfg(not(feature = "smallvec"))] use alloc::vec::Vec; use core::cmp::max; +#[cfg(feature = "smallvec")] +use smallvec::SmallVec; use super::char_data::BidiClass::{self, *}; use super::level::Level; @@ -39,7 +42,13 @@ pub fn resolve_weak<'a, T: TextSource<'a> + ?Sized>( // The previous class for the purposes of rule W1, not tracking changes from any other rules. let mut prev_class_before_w1 = sequence.sos; let mut last_strong_is_al = false; + #[cfg(feature = "smallvec")] + let mut et_run_indices = SmallVec::<[usize; 8]>::new(); // for W5 + #[cfg(not(feature = "smallvec"))] let mut et_run_indices = Vec::new(); // for W5 + #[cfg(feature = "smallvec")] + let mut bn_run_indices = SmallVec::<[usize; 8]>::new(); // for W5 + <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> + #[cfg(not(feature = "smallvec"))] let mut bn_run_indices = Vec::new(); // for W5 + <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> for (run_index, level_run) in sequence.runs.iter().enumerate() { @@ -177,7 +186,7 @@ pub fn resolve_weak<'a, T: TextSource<'a> + ?Sized>( _ => { // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> // If there was a BN run before this, that's now a part of this ET run. - et_run_indices.extend(&bn_run_indices); + et_run_indices.extend(bn_run_indices.clone()); // In case this is followed by an EN. et_run_indices.push(i); @@ -224,26 +233,29 @@ pub fn resolve_weak<'a, T: TextSource<'a> + ?Sized>( // W7. If the previous strong char was L, change EN to L. let mut last_strong_is_l = sequence.sos == L; - for run in &sequence.runs { - for i in run.clone() { - match processing_classes[i] { - EN if last_strong_is_l => { - processing_classes[i] = L; - } - L => { - last_strong_is_l = true; - } - R | AL => { - last_strong_is_l = false; - } - // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> - // Already scanning past BN here. - _ => {} + for i in sequence.runs.iter().cloned().flatten() { + match processing_classes[i] { + EN if last_strong_is_l => { + processing_classes[i] = L; } + L => { + last_strong_is_l = true; + } + R | AL => { + last_strong_is_l = false; + } + // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> + // Already scanning past BN here. + _ => {} } } } +#[cfg(feature = "smallvec")] +type BracketPairVec = SmallVec<[BracketPair; 8]>; +#[cfg(not(feature = "smallvec"))] +type BracketPairVec = Vec<BracketPair>; + /// 3.3.5 Resolving Neutral Types /// /// <http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types> @@ -267,7 +279,14 @@ pub fn resolve_neutral<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>( // > Identify the bracket pairs in the current isolating run sequence according to BD16. // We use processing_classes, not original_classes, due to BD14/BD15 - let bracket_pairs = identify_bracket_pairs(text, data_source, sequence, processing_classes); + let mut bracket_pairs = BracketPairVec::new(); + identify_bracket_pairs( + text, + data_source, + sequence, + processing_classes, + &mut bracket_pairs, + ); // > For each bracket-pair element in the list of pairs of text positions // @@ -308,7 +327,7 @@ pub fn resolve_neutral<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>( found_e = true; } else if class == not_e { found_not_e = true; - } else if class == BidiClass::EN || class == BidiClass::AN { + } else if matches!(class, BidiClass::EN | BidiClass::AN) { // > Within this scope, bidirectional types EN and AN are treated as R. if e == BidiClass::L { found_not_e = true; @@ -337,15 +356,15 @@ pub fn resolve_neutral<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>( .iter_backwards_from(pair.start, pair.start_run) .map(|i| processing_classes[i]) .find(|class| { - *class == BidiClass::L - || *class == BidiClass::R - || *class == BidiClass::EN - || *class == BidiClass::AN + matches!( + class, + BidiClass::L | BidiClass::R | BidiClass::EN | BidiClass::AN + ) }) .unwrap_or(sequence.sos); // > Within this scope, bidirectional types EN and AN are treated as R. - if previous_strong == BidiClass::EN || previous_strong == BidiClass::AN { + if matches!(previous_strong, BidiClass::EN | BidiClass::AN) { previous_strong = BidiClass::R; } @@ -413,6 +432,9 @@ pub fn resolve_neutral<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>( let mut prev_class = sequence.sos; while let Some(mut i) = indices.next() { // Process sequences of NI characters. + #[cfg(feature = "smallvec")] + let mut ni_run = SmallVec::<[usize; 8]>::new(); + #[cfg(not(feature = "smallvec"))] let mut ni_run = Vec::new(); // The BN is for <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> if is_NI(processing_classes[i]) || processing_classes[i] == BN { @@ -484,9 +506,12 @@ fn identify_bracket_pairs<'a, T: TextSource<'a> + ?Sized, D: BidiDataSource>( data_source: &D, run_sequence: &IsolatingRunSequence, original_classes: &[BidiClass], -) -> Vec<BracketPair> { - let mut ret = vec![]; - let mut stack = vec![]; + bracket_pairs: &mut BracketPairVec, +) { + #[cfg(feature = "smallvec")] + let mut stack = SmallVec::<[(char, usize, usize); 8]>::new(); + #[cfg(not(feature = "smallvec"))] + let mut stack = Vec::new(); for (run_index, level_run) in run_sequence.runs.iter().enumerate() { for (i, ch) in text.subrange(level_run.clone()).char_indices() { @@ -532,7 +557,7 @@ fn identify_bracket_pairs<'a, T: TextSource<'a> + ?Sized, D: BidiDataSource>( start_run: element.2, end_run: run_index, }; - ret.push(pair); + bracket_pairs.push(pair); // > Pop the stack through the current stack element inclusively. stack.truncate(stack_index); @@ -545,8 +570,7 @@ fn identify_bracket_pairs<'a, T: TextSource<'a> + ?Sized, D: BidiDataSource>( } // > Sort the list of pairs of text positions in ascending order based on // > the text position of the opening paired bracket. - ret.sort_by_key(|r| r.start); - ret + bracket_pairs.sort_by_key(|r| r.start); } /// 3.3.6 Resolving Implicit Levels @@ -555,11 +579,11 @@ fn identify_bracket_pairs<'a, T: TextSource<'a> + ?Sized, D: BidiDataSource>( /// /// <http://www.unicode.org/reports/tr9/#Resolving_Implicit_Levels> #[cfg_attr(feature = "flame_it", flamer::flame)] -pub fn resolve_levels(original_classes: &[BidiClass], levels: &mut [Level]) -> Level { +pub fn resolve_levels(processing_classes: &[BidiClass], levels: &mut [Level]) -> Level { let mut max_level = Level::ltr(); - assert_eq!(original_classes.len(), levels.len()); + assert_eq!(processing_classes.len(), levels.len()); for i in 0..levels.len() { - match (levels[i].is_rtl(), original_classes[i]) { + match (levels[i].is_rtl(), processing_classes[i]) { (false, AN) | (false, EN) => levels[i].raise(2).expect("Level number error"), (false, R) | (true, L) | (true, EN) | (true, AN) => { levels[i].raise(1).expect("Level number error") @@ -578,8 +602,5 @@ pub fn resolve_levels(original_classes: &[BidiClass], levels: &mut [Level]) -> L /// <http://www.unicode.org/reports/tr9/#NI> #[allow(non_snake_case)] fn is_NI(class: BidiClass) -> bool { - match class { - B | S | WS | ON | FSI | LRI | RLI | PDI => true, - _ => false, - } + matches!(class, B | S | WS | ON | FSI | LRI | RLI | PDI) } |