sofie_values/
slug_character.rs1use std::ops::RangeInclusive;
2
3use unicode_normalization::char::is_combining_mark;
4
5pub const LATIN_COMBINING_ACCENTS: RangeInclusive<char> = '\u{300}'..='\u{36f}';
7
8#[must_use]
11pub fn is_slug_character(character: char) -> bool {
12 character.to_lowercase().eq([character])
13 && (character.is_alphanumeric() || is_word_mark(character))
14 && !LATIN_COMBINING_ACCENTS.contains(&character)
15 && !sofie_core::misleads_display(character)
16}
17
18pub(crate) fn is_word_mark(character: char) -> bool {
20 is_combining_mark(character)
21 && !draws_nothing(character)
22 && !matches!(
23 character,
24 '\u{488}'..='\u{489}'
25 | '\u{1abe}'
26 | '\u{20dd}'..='\u{20e0}'
27 | '\u{20e2}'..='\u{20e4}'
28 | '\u{a670}'..='\u{a672}'
29 )
30}
31
32pub(crate) fn draws_nothing(character: char) -> bool {
35 matches!(
36 character,
37 '\u{34f}'
38 | '\u{17b4}'..='\u{17b5}'
39 | '\u{180b}'..='\u{180d}'
40 | '\u{180f}'
41 | '\u{fe00}'..='\u{fe0f}'
42 | '\u{e0100}'..='\u{e01ef}'
43 )
44}
45
46pub(crate) fn without_marks_that_draw_nothing(text: &str) -> String {
49 text.chars()
50 .filter(|&character| !draws_nothing(character))
51 .collect()
52}