basic_text_internals/
isolate_unassigned.rs1use crate::text_utils::is_private_use_area;
2use crate::unicode::CGJ;
3use std::iter::Fuse;
4use unicode_normalization::char::is_public_assigned;
5
6pub struct IsolateUnassigned<I: Iterator<Item = char>> {
8 iter: Fuse<I>,
9 need_cgj: bool,
10 have_cgj: bool,
11 deferred: Option<char>,
12}
13
14impl<I: Iterator<Item = char>> IsolateUnassigned<I> {
15 #[inline]
16 pub fn new(iter: I) -> Self {
17 Self {
18 iter: Iterator::fuse(iter),
19 need_cgj: false,
20 have_cgj: false,
21 deferred: None,
22 }
23 }
24}
25
26impl<I: Iterator<Item = char>> Iterator for IsolateUnassigned<I> {
27 type Item = char;
28
29 #[inline]
30 fn next(&mut self) -> Option<char> {
31 if let Some(deferred) = self.deferred.take() {
32 return Some(deferred);
33 }
34
35 let c = self.iter.next();
36
37 match c {
38 Some(c) => {
39 let assigned = is_public_assigned(c) || is_private_use_area(c);
40 let have_cgj = c == CGJ;
41 Some(
42 if (self.need_cgj && !have_cgj) || (!assigned && !self.have_cgj) {
43 self.need_cgj = !assigned;
44 self.have_cgj = false;
45 self.deferred = Some(c);
46 CGJ
47 } else {
48 self.need_cgj = false;
49 self.have_cgj = have_cgj;
50 c
51 },
52 )
53 }
54 None => {
55 if self.need_cgj {
56 self.need_cgj = false;
57 Some(CGJ)
58 } else {
59 None
60 }
61 }
62 }
63 }
64}