textlane_core/helpers/
slug.rs1use std::collections::HashMap;
2
3use crate::helpers::slug_table::REMOVED;
4
5#[derive(Debug, Default)]
7pub struct Slugger {
8 occurrences: HashMap<String, usize>,
9}
10
11impl Slugger {
12 pub fn slug(&mut self, value: &str) -> String {
14 let original = create_slug(value);
15 let mut result = original.clone();
16 while self.occurrences.contains_key(&result) {
17 let count = self.occurrences.entry(original.clone()).or_default();
18 *count += 1;
19 result = format!("{original}-{count}");
20 }
21 self.occurrences.insert(result.clone(), 0);
22 result
23 }
24}
25
26pub fn create_slug(value: &str) -> String {
28 value
29 .to_lowercase()
30 .chars()
31 .filter(|character| !is_removed(*character))
32 .map(|character| if character == ' ' { '-' } else { character })
33 .collect()
34}
35
36fn is_removed(character: char) -> bool {
37 let code = u32::from(character);
38 REMOVED
39 .binary_search_by(|(start, end)| {
40 if *end < code {
41 std::cmp::Ordering::Less
42 } else if *start > code {
43 std::cmp::Ordering::Greater
44 } else {
45 std::cmp::Ordering::Equal
46 }
47 })
48 .is_ok()
49}