1 use crate::{transform, uppercase}; 2 3 /// This trait defines a shouty snake case conversion. 4 /// 5 /// In SHOUTY_SNAKE_CASE, word boundaries are indicated by underscores and all 6 /// words are in uppercase. 7 /// 8 /// ## Example: 9 /// 10 /// ```rust 11 /// use heck::ShoutySnakeCase; 12 /// 13 /// let sentence = "That world is growing in this minute."; 14 /// assert_eq!(sentence.to_shouty_snake_case(), "THAT_WORLD_IS_GROWING_IN_THIS_MINUTE"); 15 /// ``` 16 pub trait ShoutySnakeCase: ToOwned { 17 /// Convert this type to shouty snake case. to_shouty_snake_case(&self) -> Self::Owned18 fn to_shouty_snake_case(&self) -> Self::Owned; 19 } 20 21 /// Oh heck, ShoutySnekCase is an alias for ShoutySnakeCase. See ShoutySnakeCase for 22 /// more documentation. 23 pub trait ShoutySnekCase: ToOwned { 24 /// CONVERT THIS TYPE TO SNEK CASE. 25 #[allow(non_snake_case)] TO_SHOUTY_SNEK_CASE(&self) -> Self::Owned26 fn TO_SHOUTY_SNEK_CASE(&self) -> Self::Owned; 27 } 28 29 impl<T: ?Sized + ShoutySnakeCase> ShoutySnekCase for T { TO_SHOUTY_SNEK_CASE(&self) -> Self::Owned30 fn TO_SHOUTY_SNEK_CASE(&self) -> Self::Owned { 31 self.to_shouty_snake_case() 32 } 33 } 34 35 36 impl ShoutySnakeCase for str { to_shouty_snake_case(&self) -> Self::Owned37 fn to_shouty_snake_case(&self) -> Self::Owned { 38 transform(self, uppercase, |s| s.push('_')) 39 } 40 } 41 42 #[cfg(test)] 43 mod tests { 44 use super::ShoutySnakeCase; 45 46 macro_rules! t { 47 ($t:ident : $s1:expr => $s2:expr) => { 48 #[test] 49 fn $t() { 50 assert_eq!($s1.to_shouty_snake_case(), $s2) 51 } 52 } 53 } 54 55 t!(test1: "CamelCase" => "CAMEL_CASE"); 56 t!(test2: "This is Human case." => "THIS_IS_HUMAN_CASE"); 57 t!(test3: "MixedUP CamelCase, with some Spaces" => "MIXED_UP_CAMEL_CASE_WITH_SOME_SPACES"); 58 t!(test4: "mixed_up_snake_case with some _spaces" => "MIXED_UP_SNAKE_CASE_WITH_SOME_SPACES"); 59 t!(test5: "kebab-case" => "KEBAB_CASE"); 60 t!(test6: "SHOUTY_SNAKE_CASE" => "SHOUTY_SNAKE_CASE"); 61 t!(test7: "snake_case" => "SNAKE_CASE"); 62 t!(test8: "this-contains_ ALLKinds OfWord_Boundaries" => "THIS_CONTAINS_ALL_KINDS_OF_WORD_BOUNDARIES"); 63 t!(test9: "XΣXΣ baffle" => "XΣXΣ_BAFFLE"); 64 t!(test10: "XMLHttpRequest" => "XML_HTTP_REQUEST"); 65 } 66