use super::{cluster::Boundary, Codepoint, LineBreak, Properties, WordBreak};
use core::borrow::Borrow;
pub fn analyze<I>(chars: I) -> Analyze<I::IntoIter>
where
I: IntoIterator,
I::IntoIter: Clone,
I::Item: Borrow<char>,
{
Analyze {
chars: chars.into_iter(),
state: BoundaryState::new(),
}
}
#[derive(Clone)]
pub struct Analyze<I> {
chars: I,
state: BoundaryState,
}
impl<I> Iterator for Analyze<I>
where
I: Iterator + Clone,
I::Item: Borrow<char>,
{
type Item = (Properties, Boundary);
fn next(&mut self) -> Option<Self::Item> {
self.state.next(&mut self.chars)
}
}
impl<I> Analyze<I> {
pub fn needs_bidi_resolution(&self) -> bool {
self.state.needs_bidi
}
}
#[derive(Clone)]
struct BoundaryState {
prev: WordBreak,
prevent_next: bool,
ri_count: u8,
emoji: bool,
next_emoji: bool,
line_state: (u8, bool),
first: bool,
needs_bidi: bool,
}
impl BoundaryState {
fn new() -> Self {
Self {
prev: WordBreak::EX,
prevent_next: false,
ri_count: 0,
emoji: false,
next_emoji: false,
line_state: (sot, false),
first: true,
needs_bidi: false,
}
}
fn reset_state(&mut self) {
self.ri_count = 0;
self.emoji = false;
}
fn check_word<I>(&mut self, props: Properties, iter: &mut I) -> bool
where
I: Iterator + Clone,
I::Item: Borrow<char>,
{
use WordBreak::*;
let b = props.word_break();
let emoji = props.is_extended_pictographic();
if self.first {
self.first = false;
self.prev = b;
self.next_emoji = emoji;
if b == RI {
self.ri_count = 1;
}
return true;
}
let prev_emoji = self.emoji;
self.emoji = self.emoji || self.next_emoji;
self.next_emoji = emoji;
let a = self.prev;
self.prev = b;
if self.prevent_next {
self.prevent_next = false;
return false;
}
if a == CR && b == LF {
self.reset_state();
return false;
}
let a_mask = a.mask();
let b_mask = b.mask();
const AH_LETTER: u32 = LE.mask() | HL.mask();
const MID_NUM_LET_Q: u32 = MB.mask() | SQ.mask();
const WB3_A: u32 = NL.mask() | CR.mask() | LF.mask();
if a_mask & WB3_A != 0 || b_mask & WB3_A != 0 {
self.reset_state();
return true;
}
if a == ZWJ && emoji {
self.reset_state();
return false;
}
const WB_4: u32 = Extend.mask() | FO.mask() | ZWJ.mask();
if b_mask & WB_4 != 0 {
self.reset_state();
self.prev = a;
return false;
}
if a == WSegSpace && b == WSegSpace {
self.reset_state();
return false;
}
if a_mask & AH_LETTER != 0 {
if b_mask & (AH_LETTER | NU.mask()) != 0 {
self.reset_state();
return false;
}
if b_mask & (ML.mask() | MID_NUM_LET_Q) != 0 {
if let Some(c) = iter
.clone()
.next()
.map(|p| p.borrow().properties().word_break())
{
if c.mask() & AH_LETTER != 0 {
self.prevent_next = true;
self.reset_state();
return false;
}
}
}
}
if a == HL {
if b == SQ {
self.reset_state();
return false;
}
if b == DQ {
if let Some(c) = iter
.clone()
.next()
.map(|p| p.borrow().properties().word_break())
{
if c == HL {
self.prevent_next = true;
self.reset_state();
return false;
}
}
}
}
if a_mask & NU.mask() != 0 {
if b_mask & (NU.mask() | AH_LETTER) != 0 {
self.reset_state();
return false;
}
if b_mask & (MN.mask() | MID_NUM_LET_Q) != 0 {
if let Some(c) = iter
.clone()
.next()
.map(|p| p.borrow().properties().word_break())
{
if c == NU {
self.prevent_next = true;
self.reset_state();
return false;
}
}
}
}
if a == KA && b == KA {
self.reset_state();
return false;
}
const WB13_A: u32 = AH_LETTER | NU.mask() | KA.mask() | EX.mask();
if a_mask & WB13_A != 0 && b == EX {
self.reset_state();
return false;
}
const WB13_B: u32 = AH_LETTER | NU.mask() | KA.mask();
if a == EX && b_mask & WB13_B != 0 {
self.reset_state();
return false;
}
if prev_emoji && a == ZWJ && emoji {
self.ri_count = 0;
return false;
}
if self.ri_count == 2 {
self.reset_state();
if b == RI {
self.ri_count = 1;
}
return true;
}
if b == RI {
self.ri_count += 1;
if a != RI {
self.reset_state();
self.ri_count = 1;
return true;
}
self.emoji = false;
return false;
}
self.reset_state();
true
}
fn check_line(&mut self, props: Properties) -> Boundary {
let state = self.line_state;
let lb = props.line_break();
let val = PAIR_TABLE[state.0 as usize][lb as usize];
let mode = if val & MANDATORY_BREAK_BIT != 0 {
Boundary::Mandatory
} else if val & ALLOWED_BREAK_BIT != 0 && !state.1 {
Boundary::Line
} else {
Boundary::None
};
self.line_state = (
val & !(ALLOWED_BREAK_BIT | MANDATORY_BREAK_BIT),
lb == LineBreak::ZWJ,
);
mode
}
fn next<I>(&mut self, iter: &mut I) -> Option<(Properties, Boundary)>
where
I: Iterator + Clone,
I::Item: Borrow<char>,
{
let props = iter.next()?.borrow().properties();
let mut boundary = self.check_line(props);
let word = self.check_word(props, iter);
if boundary as u16 == 0 && word {
boundary = Boundary::Word;
}
self.needs_bidi = self.needs_bidi || props.bidi_class().needs_resolution();
Some((props, boundary))
}
}
const ALLOWED_BREAK_BIT: u8 = 0x80;
const MANDATORY_BREAK_BIT: u8 = 0x40;
#[allow(non_upper_case_globals)]
const sot: u8 = 44;
#[rustfmt::skip]
const PAIR_TABLE: [[u8; 44]; 53] = [
[1,1,130,3,132,5,134,28,8,1,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,1,235,],
[1,1,130,3,132,5,134,28,8,1,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,1,235,],
[129,129,2,3,132,5,134,28,8,2,10,11,140,141,14,15,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,50,38,39,129,41,2,235,],
[129,129,130,3,132,5,134,28,8,3,10,11,140,141,14,143,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,3,235,],
[1,1,2,3,4,5,134,28,8,4,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,37,38,39,1,41,4,235,],
[193,193,194,195,196,197,198,220,200,193,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,193,193,229,230,231,193,233,193,235,],
[129,129,130,131,132,5,134,156,8,6,10,11,140,141,14,15,144,145,146,147,148,149,22,151,152,153,26,27,156,157,158,159,160,33,162,129,129,37,38,39,129,41,6,235,],
[129,129,130,3,132,5,134,28,8,28,10,11,140,141,14,15,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,28,235,],
[129,129,130,3,132,5,134,28,8,8,10,11,140,141,14,15,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,31,32,33,162,129,129,48,38,39,129,41,8,235,],
[1,1,130,3,132,5,134,28,8,9,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,9,235,],
[1,1,130,3,132,5,134,28,8,10,10,11,140,141,14,15,144,145,18,19,148,149,22,151,152,153,26,27,28,29,158,31,32,33,162,1,1,49,38,39,1,41,10,235,],
[193,193,194,195,196,197,198,220,200,193,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,26,219,220,221,222,223,224,225,226,193,193,229,230,231,193,233,193,235,],
[129,129,130,3,132,5,134,28,8,12,10,11,140,13,14,15,144,145,146,19,148,21,22,151,152,153,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,12,235,],
[129,129,130,3,132,5,134,28,8,13,10,11,140,141,14,15,144,145,146,19,148,21,22,151,152,153,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,13,235,],
[129,129,130,3,132,5,134,28,8,14,10,11,140,141,14,15,144,145,146,19,148,21,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,14,235,],
[1,1,2,3,4,5,6,28,8,15,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,37,38,39,1,41,15,235,],
[129,129,130,3,132,5,134,28,8,16,10,11,140,141,14,15,144,145,146,19,148,21,22,151,24,25,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,16,235,],
[129,129,130,3,132,5,134,28,8,17,10,11,140,141,14,15,144,145,146,19,148,21,22,151,24,153,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,17,235,],
[1,1,130,51,132,5,134,28,8,18,10,11,140,141,14,15,144,145,18,51,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,18,235,],
[129,129,130,3,132,5,134,28,8,19,10,11,140,141,14,143,144,145,146,19,148,149,22,151,152,153,26,27,28,29,158,159,160,33,162,129,129,37,38,39,129,41,19,235,],
[129,129,130,3,132,5,134,28,8,20,10,11,140,141,14,15,144,145,146,19,148,21,22,151,152,153,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,20,235,],
[129,129,130,3,132,5,134,28,8,21,10,11,140,141,14,15,144,145,146,19,148,21,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,21,235,],
[1,1,130,3,132,5,134,28,8,22,10,11,140,141,14,15,144,145,18,19,148,149,22,151,152,153,26,27,28,29,158,159,160,33,162,1,1,37,38,39,1,41,22,235,],
[129,129,130,3,132,5,134,28,8,23,10,11,140,141,14,15,16,17,146,19,148,21,22,23,152,25,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,23,235,],
[129,129,130,3,132,5,134,28,8,24,10,11,140,141,14,15,144,145,146,19,148,21,22,151,24,153,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,24,235,],
[129,129,130,3,132,5,134,28,8,25,10,11,140,141,14,15,144,145,146,19,148,21,22,151,24,25,26,27,28,157,158,31,160,33,162,129,129,37,38,39,129,41,25,235,],
[193,193,194,195,196,197,198,220,200,193,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,193,193,229,230,231,193,233,193,235,],
[193,193,194,195,196,197,198,220,200,193,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,193,193,229,230,231,193,233,193,235,],
[129,129,130,3,132,5,134,28,8,28,10,11,140,141,14,15,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,28,235,],
[1,1,130,3,132,5,134,28,8,29,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,29,235,],
[1,1,2,3,4,5,6,28,8,30,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,46,38,39,1,41,30,235,],
[1,1,130,3,132,5,134,28,8,31,10,11,140,141,14,15,144,145,18,19,148,149,22,151,152,153,26,27,28,29,30,159,160,33,162,1,1,37,38,39,1,41,31,235,],
[1,1,130,3,132,5,134,28,8,32,10,11,12,13,14,15,16,17,18,19,20,149,22,23,24,25,26,27,28,29,30,159,160,33,162,1,1,37,38,39,1,41,32,235,],
[1,1,2,3,4,5,6,28,8,33,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,47,38,39,1,41,33,235,],
[129,129,130,3,132,5,134,28,8,34,10,11,140,141,14,15,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,52,129,129,37,38,39,129,41,34,235,],
[1,1,130,3,132,5,134,28,8,1,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,1,235,],
[1,1,130,3,132,5,134,28,8,1,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,1,235,],
[129,129,130,131,132,5,134,156,8,129,10,11,140,141,14,143,144,145,146,147,148,149,22,151,152,153,26,27,156,157,158,159,160,161,162,129,129,37,38,39,129,41,129,235,],
[129,129,130,3,132,5,134,28,8,38,10,11,140,141,14,15,144,145,18,19,148,149,22,151,152,153,26,27,28,29,158,159,160,33,162,129,129,37,38,39,129,41,38,235,],
[1,1,2,3,4,5,6,28,8,39,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,37,38,39,1,41,39,235,],
[1,1,130,3,132,5,134,28,8,1,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,1,235,],
[129,129,130,131,132,5,134,156,136,129,138,11,140,141,142,143,144,145,146,147,148,149,150,151,152,153,26,27,156,157,158,159,160,161,162,129,129,45,166,167,129,41,129,235,],
[1,1,130,3,132,5,134,28,8,42,10,11,140,141,14,15,144,145,18,19,148,21,22,151,152,153,26,27,28,29,30,31,32,33,162,1,1,37,38,39,1,41,42,235,],
[129,129,130,3,132,5,134,28,8,129,10,11,140,141,14,143,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,129,235,],
[1,1,2,3,4,5,6,28,8,1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,37,38,39,1,41,1,43,],
[129,129,130,131,132,5,134,156,136,129,138,11,140,141,142,143,144,145,146,147,148,149,150,151,152,153,26,27,156,157,158,159,160,161,162,129,129,45,166,167,129,41,129,235,],
[1,1,2,3,4,5,6,28,8,1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,46,38,39,1,41,1,235,],
[129,129,130,131,132,5,134,156,8,129,10,11,140,141,14,143,144,145,146,147,148,149,22,151,152,153,26,27,156,157,30,159,160,161,162,129,129,47,38,39,129,41,129,235,],
[129,129,130,131,132,5,134,28,8,129,10,11,140,141,14,143,144,145,146,147,148,149,22,151,152,153,26,27,28,157,158,159,160,161,162,129,129,48,38,39,129,41,129,235,],
[129,129,130,131,132,5,134,28,8,129,10,11,140,141,14,143,144,145,146,147,148,149,22,151,152,153,26,27,28,157,158,159,160,161,162,129,129,49,38,39,129,41,129,235,],
[129,129,2,131,132,5,134,156,8,129,10,11,140,141,14,143,144,145,146,147,148,149,22,151,152,153,26,27,156,157,158,159,160,161,162,129,129,50,38,39,129,41,129,235,],
[1,1,2,3,4,5,134,28,8,51,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,1,1,37,38,39,1,41,51,235,],
[129,129,130,3,132,5,134,28,8,52,10,11,140,141,14,15,144,145,146,19,148,149,22,151,152,153,26,27,28,157,158,159,160,33,162,129,129,37,38,39,129,41,52,235,],
];