#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Heading {
pub title: String,
pub id: String,
pub level: u8,
pub line: usize,
}
pub fn slugify(text: &str) -> String {
let mut result = String::with_capacity(text.len());
let mut last_was_hyphen = true;
for c in text.chars() {
if c.is_alphanumeric() || c == '.' {
result.push(c.to_ascii_lowercase());
last_was_hyphen = false;
} else if !last_was_hyphen {
result.push('-');
last_was_hyphen = true;
}
}
if result.ends_with('-') {
result.pop();
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_slugify_simple() {
assert_eq!(slugify("Hello World"), "hello-world");
}
#[test]
fn test_slugify_special_chars() {
assert_eq!(slugify("My API (v2)"), "my-api-v2");
}
#[test]
fn test_slugify_numbers() {
assert_eq!(slugify("Chapter 1: Introduction"), "chapter-1-introduction");
}
#[test]
fn test_slugify_consecutive_spaces() {
assert_eq!(slugify("a b"), "a-b");
}
#[test]
fn test_slugify_leading_trailing() {
assert_eq!(slugify(" Hello "), "hello");
}
#[test]
fn test_slugify_unicode() {
assert_eq!(slugify("Héllo Wörld"), "héllo-wörld");
}
#[test]
fn test_slugify_empty() {
assert_eq!(slugify(""), "");
assert_eq!(slugify(" "), "");
}
#[test]
fn test_slugify_dots() {
assert_eq!(slugify("i.have.dots"), "i.have.dots");
assert_eq!(slugify("config.path.default"), "config.path.default");
}
}