1 use crate::{capitalize, transform}; 2 3 /// This trait defines a title case conversion. 4 /// 5 /// In Title Case, word boundaries are indicated by spaces, and every word is 6 /// capitalized. 7 /// 8 /// ## Example: 9 /// 10 /// ```rust 11 /// use heck::TitleCase; 12 /// 13 /// let sentence = "We have always lived in slums and holes in the wall."; 14 /// assert_eq!(sentence.to_title_case(), "We Have Always Lived In Slums And Holes In The Wall"); 15 /// ``` 16 pub trait TitleCase: ToOwned { 17 /// Convert this type to title case. to_title_case(&self) -> Self::Owned18 fn to_title_case(&self) -> Self::Owned; 19 } 20 21 impl TitleCase for str { to_title_case(&self) -> String22 fn to_title_case(&self) -> String { 23 transform(self, capitalize, |s| s.push(' ')) 24 } 25 } 26 27 #[cfg(test)] 28 mod tests { 29 use super::TitleCase; 30 31 macro_rules! t { 32 ($t:ident : $s1:expr => $s2:expr) => { 33 #[test] 34 fn $t() { 35 assert_eq!($s1.to_title_case(), $s2) 36 } 37 }; 38 } 39 40 t!(test1: "CamelCase" => "Camel Case"); 41 t!(test2: "This is Human case." => "This Is Human Case"); 42 t!(test3: "MixedUP CamelCase, with some Spaces" => "Mixed Up Camel Case With Some Spaces"); 43 t!(test4: "mixed_up_ snake_case, with some _spaces" => "Mixed Up Snake Case With Some Spaces"); 44 t!(test5: "kebab-case" => "Kebab Case"); 45 t!(test6: "SHOUTY_SNAKE_CASE" => "Shouty Snake Case"); 46 t!(test7: "snake_case" => "Snake Case"); 47 t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "This Contains All Kinds Of Word Boundaries"); 48 t!(test9: "XΣXΣ baffle" => "Xσxς Baffle"); 49 t!(test10: "XMLHttpRequest" => "Xml Http Request"); 50 } 51