1pub fn floor_char_boundary(s: &str, mut index: usize) -> usize {
15 if index > s.len() {
16 index = s.len();
17 }
18 while index > 0 && !s.is_char_boundary(index) {
19 index -= 1;
20 }
21 index
22}
23
24pub fn ceil_char_boundary(s: &str, mut index: usize) -> usize {
28 if index > s.len() {
29 index = s.len();
30 }
31 while index < s.len() && !s.is_char_boundary(index) {
32 index += 1;
33 }
34 index
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn snaps_multibyte_scalars_without_passing_the_ends() {
43 let text = "ó📄你";
44 assert_eq!(floor_char_boundary(text, 0), 0);
45 assert_eq!(floor_char_boundary(text, 1), 0);
46 assert_eq!(ceil_char_boundary(text, 1), 2);
47 assert_eq!(floor_char_boundary(text, text.len() + 5), text.len());
48 assert_eq!(ceil_char_boundary(text, text.len()), text.len());
49 assert!(text.is_char_boundary(floor_char_boundary(text, 3)));
50 assert!(text.is_char_boundary(ceil_char_boundary(text, 3)));
51 }
52}