unicode_normalize_aligned/
char.rs1use crate::props::{self, hangul, Props};
4
5#[inline]
7pub fn canonical_combining_class(c: char) -> u8 {
8 Props::of(c).ccc()
9}
10
11#[inline]
13pub fn is_combining_mark(c: char) -> bool {
14 Props::of(c).is_combining_mark()
15}
16
17#[inline]
21pub fn compose(a: char, b: char) -> Option<char> {
22 hangul::compose(a, b).or_else(|| props::compose_pair(a, b))
23}
24
25pub fn decompose_canonical<F: FnMut(char)>(c: char, mut emit: F) {
28 if (c as u32) < 0x80 || !Props::of(c).nfd_no() {
29 emit(c);
30 return;
31 }
32 if let Some((l, v, t)) = hangul::decompose(c) {
33 emit(l);
34 emit(v);
35 if let Some(t) = t {
36 emit(t);
37 }
38 return;
39 }
40 match props::canonical(c) {
41 Some(seq) => seq.iter().copied().for_each(emit),
42 None => emit(c),
43 }
44}
45
46pub fn decompose_compatible<F: FnMut(char)>(c: char, mut emit: F) {
49 let p = Props::of(c);
50 if (c as u32) < 0x80 || !p.nfkd_no() {
51 emit(c);
52 return;
53 }
54 if let Some((l, v, t)) = hangul::decompose(c) {
55 emit(l);
56 emit(v);
57 if let Some(t) = t {
58 emit(t);
59 }
60 return;
61 }
62 let seq = if p.has_compat() {
63 props::compat_distinct(c)
64 } else {
65 props::canonical(c)
66 };
67 match seq {
68 Some(seq) => seq.iter().copied().for_each(emit),
69 None => emit(c),
70 }
71}