Skip to content

Commit 41a0253

Browse files
committed
Fix patterns of provide_context gets panicked
This PR fixes two cases where provide_context panics even though the previous call of `is_boundary` returns a PreContext error. The primary cause is `provide_context` assumes its state as Regional or Emoji; otherwise it gets panicked with 'invalid state!' However: - if the chunk starts with the cursor position, it requires pre-context for `cat_before` (and that's necessary for some cases indeed). so provide_context should fill `cat_before` in such case. - if both `cat_before` and `cat_after` are RIS and the boundary is undecided by the chunk, it requires pre-context but it does not set its state to Regional. This is done by setting state within `handle_regional`.
1 parent 611eaa7 commit 41a0253

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/grapheme.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,10 @@ impl GraphemeCursor {
360360
match self.state {
361361
GraphemeState::Regional => self.handle_regional(chunk, chunk_start),
362362
GraphemeState::Emoji => self.handle_emoji(chunk, chunk_start),
363-
_ => panic!("invalid state")
363+
_ => if self.cat_before.is_none() && self.offset == chunk.len() + chunk_start {
364+
let ch = chunk.chars().rev().next().unwrap();
365+
self.cat_before = Some(gr::grapheme_category(ch));
366+
},
364367
}
365368
}
366369

@@ -406,6 +409,7 @@ impl GraphemeCursor {
406409
return;
407410
}
408411
self.pre_context_offset = Some(chunk_start);
412+
self.state = GraphemeState::Regional;
409413
}
410414

411415
fn handle_emoji(&mut self, chunk: &str, chunk_start: usize) {
@@ -428,6 +432,7 @@ impl GraphemeCursor {
428432
return;
429433
}
430434
self.pre_context_offset = Some(chunk_start);
435+
self.state = GraphemeState::Emoji;
431436
}
432437

433438
/// Determine whether the current cursor location is a grapheme cluster boundary.
@@ -659,3 +664,21 @@ impl GraphemeCursor {
659664
}
660665
}
661666
}
667+
668+
#[test]
669+
fn test_grapheme_cursor_ris_precontext() {
670+
let s = "\u{1f1fa}\u{1f1f8}\u{1f1fa}\u{1f1f8}\u{1f1fa}\u{1f1f8}";
671+
let mut c = GraphemeCursor::new(8, s.len(), true);
672+
assert_eq!(c.is_boundary(&s[4..], 4), Err(GraphemeIncomplete::PreContext(4)));
673+
c.provide_context(&s[..4], 0);
674+
assert_eq!(c.is_boundary(&s[4..], 4), Ok(true));
675+
}
676+
677+
#[test]
678+
fn test_grapheme_cursor_chunk_start_require_precontext() {
679+
let s = "\r\n";
680+
let mut c = GraphemeCursor::new(1, s.len(), true);
681+
assert_eq!(c.is_boundary(&s[1..], 1), Err(GraphemeIncomplete::PreContext(1)));
682+
c.provide_context(&s[..1], 0);
683+
assert_eq!(c.is_boundary(&s[1..], 1), Ok(false));
684+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy