1 //! This example shows how to implement functions that make queries about
2 //! grapheme boundaries on a `Rope` or `RopeSlice`. This also serves as a
3 //! good starting point for similar functions for other kinds of segementation,
4 //! such as word boundaries.
5
6 #![allow(dead_code)]
7
8 extern crate ropey;
9 extern crate unicode_segmentation;
10
11 use ropey::{str_utils::byte_to_char_idx, RopeSlice};
12 use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};
13
main()14 fn main() {}
15
16 /// Finds the previous grapheme boundary before the given char position.
prev_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> usize17 fn prev_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> usize {
18 // Bounds check
19 debug_assert!(char_idx <= slice.len_chars());
20
21 // We work with bytes for this, so convert.
22 let byte_idx = slice.char_to_byte(char_idx);
23
24 // Get the chunk with our byte index in it.
25 let (mut chunk, mut chunk_byte_idx, mut chunk_char_idx, _) = slice.chunk_at_byte(byte_idx);
26
27 // Set up the grapheme cursor.
28 let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);
29
30 // Find the previous grapheme cluster boundary.
31 loop {
32 match gc.prev_boundary(chunk, chunk_byte_idx) {
33 Ok(None) => return 0,
34 Ok(Some(n)) => {
35 let tmp = byte_to_char_idx(chunk, n - chunk_byte_idx);
36 return chunk_char_idx + tmp;
37 }
38 Err(GraphemeIncomplete::PrevChunk) => {
39 let (a, b, c, _) = slice.chunk_at_byte(chunk_byte_idx - 1);
40 chunk = a;
41 chunk_byte_idx = b;
42 chunk_char_idx = c;
43 }
44 Err(GraphemeIncomplete::PreContext(n)) => {
45 let ctx_chunk = slice.chunk_at_byte(n - 1).0;
46 gc.provide_context(ctx_chunk, n - ctx_chunk.len());
47 }
48 _ => unreachable!(),
49 }
50 }
51 }
52
53 /// Finds the next grapheme boundary after the given char position.
next_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> usize54 fn next_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> usize {
55 // Bounds check
56 debug_assert!(char_idx <= slice.len_chars());
57
58 // We work with bytes for this, so convert.
59 let byte_idx = slice.char_to_byte(char_idx);
60
61 // Get the chunk with our byte index in it.
62 let (mut chunk, mut chunk_byte_idx, mut chunk_char_idx, _) = slice.chunk_at_byte(byte_idx);
63
64 // Set up the grapheme cursor.
65 let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);
66
67 // Find the next grapheme cluster boundary.
68 loop {
69 match gc.next_boundary(chunk, chunk_byte_idx) {
70 Ok(None) => return slice.len_chars(),
71 Ok(Some(n)) => {
72 let tmp = byte_to_char_idx(chunk, n - chunk_byte_idx);
73 return chunk_char_idx + tmp;
74 }
75 Err(GraphemeIncomplete::NextChunk) => {
76 chunk_byte_idx += chunk.len();
77 let (a, _, c, _) = slice.chunk_at_byte(chunk_byte_idx);
78 chunk = a;
79 chunk_char_idx = c;
80 }
81 Err(GraphemeIncomplete::PreContext(n)) => {
82 let ctx_chunk = slice.chunk_at_byte(n - 1).0;
83 gc.provide_context(ctx_chunk, n - ctx_chunk.len());
84 }
85 _ => unreachable!(),
86 }
87 }
88 }
89
90 /// Returns whether the given char position is a grapheme boundary.
is_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> bool91 fn is_grapheme_boundary(slice: &RopeSlice, char_idx: usize) -> bool {
92 // Bounds check
93 debug_assert!(char_idx <= slice.len_chars());
94
95 // We work with bytes for this, so convert.
96 let byte_idx = slice.char_to_byte(char_idx);
97
98 // Get the chunk with our byte index in it.
99 let (chunk, chunk_byte_idx, _, _) = slice.chunk_at_byte(byte_idx);
100
101 // Set up the grapheme cursor.
102 let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);
103
104 // Determine if the given position is a grapheme cluster boundary.
105 loop {
106 match gc.is_boundary(chunk, chunk_byte_idx) {
107 Ok(n) => return n,
108 Err(GraphemeIncomplete::PreContext(n)) => {
109 let (ctx_chunk, ctx_byte_start, _, _) = slice.chunk_at_byte(n - 1);
110 gc.provide_context(ctx_chunk, ctx_byte_start);
111 }
112 _ => unreachable!(),
113 }
114 }
115 }
116
117 #[cfg(test)]
118 #[rustfmt::skip] // Because of the crazy long graphemes
119 mod tests {
120 use super::*;
121 use ropey::Rope;
122
123 #[test]
prev_grapheme()124 fn prev_grapheme() {
125 let r = Rope::from_str("Hẽ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃llõ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃ wõ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃rld!");
126 let mut idx = r.len_chars();
127
128 idx = prev_grapheme_boundary(&r.slice(..), idx);
129 assert_eq!(idx, 2705);
130 idx = prev_grapheme_boundary(&r.slice(..), idx);
131 assert_eq!(idx, 2704);
132 idx = prev_grapheme_boundary(&r.slice(..), idx);
133 assert_eq!(idx, 2703);
134 idx = prev_grapheme_boundary(&r.slice(..), idx);
135 assert_eq!(idx, 2702);
136 idx = prev_grapheme_boundary(&r.slice(..), idx);
137 assert_eq!(idx, 984);
138 idx = prev_grapheme_boundary(&r.slice(..), idx);
139 assert_eq!(idx, 983);
140 idx = prev_grapheme_boundary(&r.slice(..), idx);
141 assert_eq!(idx, 982);
142 idx = prev_grapheme_boundary(&r.slice(..), idx);
143 assert_eq!(idx, 446);
144 idx = prev_grapheme_boundary(&r.slice(..), idx);
145 assert_eq!(idx, 445);
146 idx = prev_grapheme_boundary(&r.slice(..), idx);
147 assert_eq!(idx, 444);
148 idx = prev_grapheme_boundary(&r.slice(..), idx);
149 assert_eq!(idx, 1);
150 idx = prev_grapheme_boundary(&r.slice(..), idx);
151 assert_eq!(idx, 0);
152 idx = prev_grapheme_boundary(&r.slice(..), idx);
153 assert_eq!(idx, 0);
154 }
155
156 #[test]
next_grapheme()157 fn next_grapheme() {
158 let r = Rope::from_str("Hẽ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃llõ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃ wõ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃rld!");
159 let mut idx = 0;
160
161 idx = next_grapheme_boundary(&r.slice(..), idx);
162 assert_eq!(idx, 1);
163 idx = next_grapheme_boundary(&r.slice(..), idx);
164 assert_eq!(idx, 444);
165 idx = next_grapheme_boundary(&r.slice(..), idx);
166 assert_eq!(idx, 445);
167 idx = next_grapheme_boundary(&r.slice(..), idx);
168 assert_eq!(idx, 446);
169 idx = next_grapheme_boundary(&r.slice(..), idx);
170 assert_eq!(idx, 982);
171 idx = next_grapheme_boundary(&r.slice(..), idx);
172 assert_eq!(idx, 983);
173 idx = next_grapheme_boundary(&r.slice(..), idx);
174 assert_eq!(idx, 984);
175 idx = next_grapheme_boundary(&r.slice(..), idx);
176 assert_eq!(idx, 2702);
177 idx = next_grapheme_boundary(&r.slice(..), idx);
178 assert_eq!(idx, 2703);
179 idx = next_grapheme_boundary(&r.slice(..), idx);
180 assert_eq!(idx, 2704);
181 idx = next_grapheme_boundary(&r.slice(..), idx);
182 assert_eq!(idx, 2705);
183 idx = next_grapheme_boundary(&r.slice(..), idx);
184 assert_eq!(idx, 2706);
185 idx = next_grapheme_boundary(&r.slice(..), idx);
186 assert_eq!(idx, 2706);
187 }
188
189 #[test]
is_grapheme_boundary_01()190 fn is_grapheme_boundary_01() {
191 let r = Rope::from_str("Hẽ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃llõ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃ wõ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃rld!");
192
193 assert_eq!(is_grapheme_boundary(&r.slice(..), 0), true);
194
195 assert_eq!(is_grapheme_boundary(&r.slice(..), 1), true);
196 assert_eq!(is_grapheme_boundary(&r.slice(..), 2), false);
197 assert_eq!(is_grapheme_boundary(&r.slice(..), 200), false);
198 assert_eq!(is_grapheme_boundary(&r.slice(..), 443), false);
199 assert_eq!(is_grapheme_boundary(&r.slice(..), 444), true);
200
201 assert_eq!(is_grapheme_boundary(&r.slice(..), 445), true);
202
203 assert_eq!(is_grapheme_boundary(&r.slice(..), 446), true);
204 assert_eq!(is_grapheme_boundary(&r.slice(..), 447), false);
205 assert_eq!(is_grapheme_boundary(&r.slice(..), 600), false);
206 assert_eq!(is_grapheme_boundary(&r.slice(..), 981), false);
207 assert_eq!(is_grapheme_boundary(&r.slice(..), 982), true);
208
209 assert_eq!(is_grapheme_boundary(&r.slice(..), 983), true);
210
211 assert_eq!(is_grapheme_boundary(&r.slice(..), 984), true);
212 assert_eq!(is_grapheme_boundary(&r.slice(..), 985), false);
213 assert_eq!(is_grapheme_boundary(&r.slice(..), 1400), false);
214 assert_eq!(is_grapheme_boundary(&r.slice(..), 2701), false);
215 assert_eq!(is_grapheme_boundary(&r.slice(..), 2702), true);
216
217 assert_eq!(is_grapheme_boundary(&r.slice(..), 2703), true);
218 assert_eq!(is_grapheme_boundary(&r.slice(..), 2704), true);
219 assert_eq!(is_grapheme_boundary(&r.slice(..), 2705), true);
220 assert_eq!(is_grapheme_boundary(&r.slice(..), 2706), true);
221 }
222
223 #[test]
prev_grapheme_regional_symbols()224 fn prev_grapheme_regional_symbols() {
225 let r = Rope::from_str("");
226 let mut idx = r.len_chars();
227
228 idx = prev_grapheme_boundary(&r.slice(..), idx);
229 assert_eq!(idx, 46);
230 idx = prev_grapheme_boundary(&r.slice(..), idx);
231 assert_eq!(idx, 44);
232 idx = prev_grapheme_boundary(&r.slice(..), idx);
233 assert_eq!(idx, 42);
234 idx = prev_grapheme_boundary(&r.slice(..), idx);
235 assert_eq!(idx, 40);
236 idx = prev_grapheme_boundary(&r.slice(..), idx);
237 assert_eq!(idx, 38);
238 idx = prev_grapheme_boundary(&r.slice(..), idx);
239 assert_eq!(idx, 36);
240 idx = prev_grapheme_boundary(&r.slice(..), idx);
241 assert_eq!(idx, 34);
242 idx = prev_grapheme_boundary(&r.slice(..), idx);
243 assert_eq!(idx, 32);
244 idx = prev_grapheme_boundary(&r.slice(..), idx);
245 assert_eq!(idx, 30);
246 idx = prev_grapheme_boundary(&r.slice(..), idx);
247 assert_eq!(idx, 28);
248 idx = prev_grapheme_boundary(&r.slice(..), idx);
249 assert_eq!(idx, 26);
250 idx = prev_grapheme_boundary(&r.slice(..), idx);
251 assert_eq!(idx, 24);
252 idx = prev_grapheme_boundary(&r.slice(..), idx);
253 assert_eq!(idx, 22);
254 idx = prev_grapheme_boundary(&r.slice(..), idx);
255 assert_eq!(idx, 20);
256 idx = prev_grapheme_boundary(&r.slice(..), idx);
257 assert_eq!(idx, 18);
258 idx = prev_grapheme_boundary(&r.slice(..), idx);
259 assert_eq!(idx, 16);
260 idx = prev_grapheme_boundary(&r.slice(..), idx);
261 assert_eq!(idx, 14);
262 idx = prev_grapheme_boundary(&r.slice(..), idx);
263 assert_eq!(idx, 12);
264 idx = prev_grapheme_boundary(&r.slice(..), idx);
265 assert_eq!(idx, 10);
266 idx = prev_grapheme_boundary(&r.slice(..), idx);
267 assert_eq!(idx, 8);
268 idx = prev_grapheme_boundary(&r.slice(..), idx);
269 assert_eq!(idx, 6);
270 idx = prev_grapheme_boundary(&r.slice(..), idx);
271 assert_eq!(idx, 4);
272 idx = prev_grapheme_boundary(&r.slice(..), idx);
273 assert_eq!(idx, 2);
274 idx = prev_grapheme_boundary(&r.slice(..), idx);
275 assert_eq!(idx, 0);
276 idx = prev_grapheme_boundary(&r.slice(..), idx);
277 assert_eq!(idx, 0);
278 }
279
280 #[test]
next_grapheme_regional_symbols()281 fn next_grapheme_regional_symbols() {
282 let r = Rope::from_str("");
283 let mut idx = 0;
284
285 idx = next_grapheme_boundary(&r.slice(..), idx);
286 assert_eq!(idx, 2);
287 idx = next_grapheme_boundary(&r.slice(..), idx);
288 assert_eq!(idx, 4);
289 idx = next_grapheme_boundary(&r.slice(..), idx);
290 assert_eq!(idx, 6);
291 idx = next_grapheme_boundary(&r.slice(..), idx);
292 assert_eq!(idx, 8);
293 idx = next_grapheme_boundary(&r.slice(..), idx);
294 assert_eq!(idx, 10);
295 idx = next_grapheme_boundary(&r.slice(..), idx);
296 assert_eq!(idx, 12);
297 idx = next_grapheme_boundary(&r.slice(..), idx);
298 assert_eq!(idx, 14);
299 idx = next_grapheme_boundary(&r.slice(..), idx);
300 assert_eq!(idx, 16);
301 idx = next_grapheme_boundary(&r.slice(..), idx);
302 assert_eq!(idx, 18);
303 idx = next_grapheme_boundary(&r.slice(..), idx);
304 assert_eq!(idx, 20);
305 idx = next_grapheme_boundary(&r.slice(..), idx);
306 assert_eq!(idx, 22);
307 idx = next_grapheme_boundary(&r.slice(..), idx);
308 assert_eq!(idx, 24);
309 idx = next_grapheme_boundary(&r.slice(..), idx);
310 assert_eq!(idx, 26);
311 idx = next_grapheme_boundary(&r.slice(..), idx);
312 assert_eq!(idx, 28);
313 idx = next_grapheme_boundary(&r.slice(..), idx);
314 assert_eq!(idx, 30);
315 idx = next_grapheme_boundary(&r.slice(..), idx);
316 assert_eq!(idx, 32);
317 idx = next_grapheme_boundary(&r.slice(..), idx);
318 assert_eq!(idx, 34);
319 idx = next_grapheme_boundary(&r.slice(..), idx);
320 assert_eq!(idx, 36);
321 idx = next_grapheme_boundary(&r.slice(..), idx);
322 assert_eq!(idx, 38);
323 idx = next_grapheme_boundary(&r.slice(..), idx);
324 assert_eq!(idx, 40);
325 idx = next_grapheme_boundary(&r.slice(..), idx);
326 assert_eq!(idx, 42);
327 idx = next_grapheme_boundary(&r.slice(..), idx);
328 assert_eq!(idx, 44);
329 idx = next_grapheme_boundary(&r.slice(..), idx);
330 assert_eq!(idx, 46);
331 idx = next_grapheme_boundary(&r.slice(..), idx);
332 assert_eq!(idx, 47);
333 idx = next_grapheme_boundary(&r.slice(..), idx);
334 assert_eq!(idx, 47);
335 }
336
337 #[test]
is_grapheme_boundary_regional_symbols()338 fn is_grapheme_boundary_regional_symbols() {
339 let r = Rope::from_str("");
340
341 assert_eq!(is_grapheme_boundary(&r.slice(..), 0), true);
342 assert_eq!(is_grapheme_boundary(&r.slice(..), 1), false);
343 assert_eq!(is_grapheme_boundary(&r.slice(..), 2), true);
344 assert_eq!(is_grapheme_boundary(&r.slice(..), 3), false);
345 assert_eq!(is_grapheme_boundary(&r.slice(..), 4), true);
346 assert_eq!(is_grapheme_boundary(&r.slice(..), 5), false);
347 assert_eq!(is_grapheme_boundary(&r.slice(..), 6), true);
348 assert_eq!(is_grapheme_boundary(&r.slice(..), 7), false);
349 assert_eq!(is_grapheme_boundary(&r.slice(..), 8), true);
350 assert_eq!(is_grapheme_boundary(&r.slice(..), 9), false);
351 assert_eq!(is_grapheme_boundary(&r.slice(..), 10), true);
352 assert_eq!(is_grapheme_boundary(&r.slice(..), 11), false);
353 assert_eq!(is_grapheme_boundary(&r.slice(..), 12), true);
354 assert_eq!(is_grapheme_boundary(&r.slice(..), 13), false);
355 assert_eq!(is_grapheme_boundary(&r.slice(..), 14), true);
356 assert_eq!(is_grapheme_boundary(&r.slice(..), 15), false);
357 assert_eq!(is_grapheme_boundary(&r.slice(..), 16), true);
358 assert_eq!(is_grapheme_boundary(&r.slice(..), 17), false);
359 assert_eq!(is_grapheme_boundary(&r.slice(..), 18), true);
360 assert_eq!(is_grapheme_boundary(&r.slice(..), 19), false);
361 assert_eq!(is_grapheme_boundary(&r.slice(..), 20), true);
362 assert_eq!(is_grapheme_boundary(&r.slice(..), 21), false);
363 assert_eq!(is_grapheme_boundary(&r.slice(..), 22), true);
364 assert_eq!(is_grapheme_boundary(&r.slice(..), 23), false);
365 assert_eq!(is_grapheme_boundary(&r.slice(..), 24), true);
366 assert_eq!(is_grapheme_boundary(&r.slice(..), 25), false);
367 assert_eq!(is_grapheme_boundary(&r.slice(..), 26), true);
368 assert_eq!(is_grapheme_boundary(&r.slice(..), 27), false);
369 assert_eq!(is_grapheme_boundary(&r.slice(..), 28), true);
370 assert_eq!(is_grapheme_boundary(&r.slice(..), 29), false);
371 assert_eq!(is_grapheme_boundary(&r.slice(..), 30), true);
372 assert_eq!(is_grapheme_boundary(&r.slice(..), 31), false);
373 assert_eq!(is_grapheme_boundary(&r.slice(..), 32), true);
374 assert_eq!(is_grapheme_boundary(&r.slice(..), 33), false);
375 assert_eq!(is_grapheme_boundary(&r.slice(..), 34), true);
376 assert_eq!(is_grapheme_boundary(&r.slice(..), 35), false);
377 assert_eq!(is_grapheme_boundary(&r.slice(..), 36), true);
378 assert_eq!(is_grapheme_boundary(&r.slice(..), 37), false);
379 assert_eq!(is_grapheme_boundary(&r.slice(..), 38), true);
380 assert_eq!(is_grapheme_boundary(&r.slice(..), 39), false);
381 assert_eq!(is_grapheme_boundary(&r.slice(..), 40), true);
382 assert_eq!(is_grapheme_boundary(&r.slice(..), 41), false);
383 assert_eq!(is_grapheme_boundary(&r.slice(..), 42), true);
384 assert_eq!(is_grapheme_boundary(&r.slice(..), 43), false);
385 assert_eq!(is_grapheme_boundary(&r.slice(..), 44), true);
386 assert_eq!(is_grapheme_boundary(&r.slice(..), 45), false);
387 assert_eq!(is_grapheme_boundary(&r.slice(..), 46), true);
388 assert_eq!(is_grapheme_boundary(&r.slice(..), 47), true);
389 }
390 }
391