extern crate deunicode;
use deunicode::deunicode_char;
pub fn slugify<S: AsRef<str>>(s: S) -> String {
_slugify(s.as_ref())
}
fn _slugify(s: &str) -> String {
let mut slug: Vec<u8> = Vec::with_capacity(s.len());
let mut prev_is_dash = true;
{
let mut push_char = |x: u8| {
match x {
b'a'..=b'z' | b'0'..=b'9' => {
prev_is_dash = false;
slug.push(x);
}
b'A'..=b'Z' => {
prev_is_dash = false;
slug.push(x - b'A' + b'a');
}
_ => {
if !prev_is_dash {
slug.push(b'-');
prev_is_dash = true;
}
}
}
};
for c in s.chars() {
if c.is_ascii() {
(push_char)(c as u8);
} else {
for &cx in deunicode_char(c).unwrap_or("-").as_bytes() {
(push_char)(cx);
}
}
}
}
let mut string = unsafe { String::from_utf8_unchecked(slug) };
if string.ends_with('-') {
string.pop();
}
string.shrink_to_fit();
string
}
pub fn slugify_normal<S: AsRef<str>>(s: S, leave_size : bool) -> String {
_slugify_normal(s.as_ref(),leave_size)
}
fn _slugify_normal(s: &str, leave_size : bool) -> String {
let mut slug: Vec<u8> = Vec::with_capacity(s.len());
let mut prev_is_dash = true;
let mut empty_space_was = true;
let mut dot_was_before = false;
{
let mut push_char = |x: u8| {
match x {
b'a'..=b'z' | b'0'..=b'9' => {
prev_is_dash = false;
dot_was_before = false;
empty_space_was = false;
slug.push(x);
}
b'A'..=b'Z' => {
prev_is_dash = false;
dot_was_before = false;
empty_space_was = false;
if leave_size {
slug.push(x);
} else {
slug.push(x - b'A' + b'a');
}
}
b' ' | b'_' => {
if !empty_space_was {
slug.push(x);
prev_is_dash = false;
dot_was_before = false;
empty_space_was = true;
}
}
b'.' => {
if !dot_was_before {
slug.push(x);
prev_is_dash = false;
dot_was_before = true;
empty_space_was = false;
}
}
_ => {
if !prev_is_dash {
slug.push(b'-');
prev_is_dash = true;
dot_was_before = false;
empty_space_was = false;
}
}
}
};
for c in s.chars() {
if c.is_ascii() {
(push_char)(c as u8);
} else {
for &cx in deunicode_char(c).unwrap_or("-").as_bytes() {
(push_char)(cx);
}
}
}
}
let mut string = unsafe { String::from_utf8_unchecked(slug) };
loop {
if string.ends_with('-') {
string.pop();
continue;
}
if string.ends_with(' ') {
string.pop();
continue;
}
break;
}
string.shrink_to_fit();
string
}