1use std::borrow::Cow;
2use std::ffi::OsStr;
3use std::path::Path;
4
5pub fn precompose(s: Cow<'_, str>) -> Cow<'_, str> {
9 use unicode_normalization::UnicodeNormalization;
10 if s.as_ref().nfc().cmp(s.as_ref().chars()).is_eq() {
11 s
12 } else {
13 Cow::Owned(s.as_ref().nfc().collect())
14 }
15}
16
17pub fn decompose(s: Cow<'_, str>) -> Cow<'_, str> {
21 use unicode_normalization::UnicodeNormalization;
22 if s.as_ref().nfd().cmp(s.as_ref().chars()).is_eq() {
23 s
24 } else {
25 Cow::Owned(s.as_ref().nfd().collect())
26 }
27}
28
29pub fn precompose_path(path: Cow<'_, Path>) -> Cow<'_, Path> {
33 match path.to_str() {
34 None => path,
35 Some(maybe_decomposed) => match precompose(maybe_decomposed.into()) {
36 Cow::Borrowed(_) => path,
37 Cow::Owned(precomposed) => Cow::Owned(precomposed.into()),
38 },
39 }
40}
41
42pub fn precompose_os_string(name: Cow<'_, OsStr>) -> Cow<'_, OsStr> {
46 match name.to_str() {
47 None => name,
48 Some(maybe_decomposed) => match precompose(maybe_decomposed.into()) {
49 Cow::Borrowed(_) => name,
50 Cow::Owned(precomposed) => Cow::Owned(precomposed.into()),
51 },
52 }
53}
54
55#[cfg(feature = "bstr")]
59pub fn precompose_bstr(s: Cow<'_, bstr::BStr>) -> Cow<'_, bstr::BStr> {
60 use bstr::ByteSlice;
61 match s.to_str().ok() {
62 None => s,
63 Some(maybe_decomposed) => match precompose(maybe_decomposed.into()) {
64 Cow::Borrowed(_) => s,
65 Cow::Owned(precomposed) => Cow::Owned(precomposed.into()),
66 },
67 }
68}