diff options
Diffstat (limited to 'third_party/rust/Inflector/src')
24 files changed, 5015 insertions, 0 deletions
diff --git a/third_party/rust/Inflector/src/cases/camelcase/mod.rs b/third_party/rust/Inflector/src/cases/camelcase/mod.rs new file mode 100644 index 0000000000..b09ddc65b2 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/camelcase/mod.rs @@ -0,0 +1,370 @@ +#![deny(warnings)] +use cases::case::*; + +/// Converts a `&str` to camelCase `String` +/// +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "FooBar3"; +/// let expected_string: String = "fooBar3".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::to_camel_case; +/// let mock_string: &str = "Foo-Bar"; +/// let expected_string: String = "fooBar".to_string(); +/// let asserted_string: String = to_camel_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_camel_case(non_camelized_string: &str) -> String { + let options = CamelOptions { + new_word: false, + last_char: ' ', + first_word: false, + injectable_char: ' ', + has_seperator: false, + inverted: false, + }; + to_case_camel_like(&non_camelized_string, options) +} + +/// Determines if a `&str` is camelCase bool`` +/// +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "Foo"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "foo"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "fooBarIsAReallyReally3LongString"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::camelcase::is_camel_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_camel_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +pub fn is_camel_case(test_string: &str) -> bool { + to_camel_case(&test_string.clone()) == test_string +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_camel0(b: &mut Bencher) { + b.iter(|| { + let test_string = "Foo bar"; + super::to_camel_case(test_string) + }); + } + + #[bench] + fn bench_camel1(b: &mut Bencher) { + b.iter(|| { + let test_string = "foo_bar"; + super::to_camel_case(test_string) + }); + } + + #[bench] + fn bench_camel2(b: &mut Bencher) { + b.iter(|| { + let test_string = "fooBar"; + super::to_camel_case(test_string) + }); + } + + #[bench] + fn bench_is_camel(b: &mut Bencher) { + b.iter(|| { + let test_string: &str = "Foo bar"; + super::is_camel_case(test_string) + }); + } +} + +#[cfg(test)] +mod tests { + use ::to_camel_case; + use ::is_camel_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "fooBar".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "robertCMartin".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "randomTextWithBadChars".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "trailingBadChars".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "leadingBadChars".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "wrappedInBadChars".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "hasASign".to_owned(); + assert_eq!(to_camel_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_camel_case(&convertable_string), false) + } +} + diff --git a/third_party/rust/Inflector/src/cases/case/mod.rs b/third_party/rust/Inflector/src/cases/case/mod.rs new file mode 100644 index 0000000000..bb4c3d2e33 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/case/mod.rs @@ -0,0 +1,303 @@ +#![deny(warnings)] +#[allow(unknown_lints)] +#[allow(unused_imports)] +use std::ascii::*; + +pub struct CamelOptions { + pub new_word: bool, + pub last_char: char, + pub first_word: bool, + pub injectable_char: char, + pub has_seperator: bool, + pub inverted: bool, +} + +pub fn to_case_snake_like(convertable_string: &str, replace_with: &str, case: &str) -> String { + let mut first_character: bool = true; + let mut result: String = String::with_capacity(convertable_string.len() * 2); + for char_with_index in trim_right(convertable_string).char_indices() { + if char_is_seperator(&char_with_index.1) { + if !first_character { + first_character = true; + result.push(replace_with.chars().nth(0).unwrap_or('_')); + } + } else if requires_seperator(char_with_index, first_character, &convertable_string) { + first_character = false; + result = snake_like_with_seperator(result, replace_with, &char_with_index.1, case) + } else { + first_character = false; + result = snake_like_no_seperator(result, &char_with_index.1, case) + } + } + result +} + +pub fn to_case_camel_like(convertable_string: &str, camel_options: CamelOptions) -> String { + let mut new_word: bool = camel_options.new_word; + let mut first_word: bool = camel_options.first_word; + let mut last_char: char = camel_options.last_char; + let mut found_real_char: bool = false; + let mut result: String = String::with_capacity(convertable_string.len() * 2); + for character in trim_right(convertable_string).chars() { + if char_is_seperator(&character) && found_real_char { + new_word = true; + } else if !found_real_char && is_not_alphanumeric(character) { + continue; + } else if character.is_numeric() { + found_real_char = true; + new_word = true; + result.push(character); + } else if last_char_lower_current_is_upper_or_new_word(new_word, last_char, character) { + found_real_char = true; + new_word = false; + result = append_on_new_word(result, first_word, character, &camel_options); + first_word = false; + } else { + found_real_char = true; + last_char = character; + result.push(character.to_ascii_lowercase()); + } + } + result +} + +#[inline] +fn append_on_new_word(mut result: String, first_word: bool, character: char, camel_options: &CamelOptions) -> String { + if not_first_word_and_has_seperator(first_word, camel_options.has_seperator) { + result.push(camel_options.injectable_char); + } + if first_word_or_not_inverted(first_word, camel_options.inverted) { + result.push(character.to_ascii_uppercase()); + } else { + result.push(character.to_ascii_lowercase()); + } + result +} + +fn not_first_word_and_has_seperator(first_word: bool, has_seperator: bool) -> bool { + has_seperator && !first_word +} + +fn first_word_or_not_inverted(first_word: bool, inverted: bool) -> bool { + !inverted || first_word +} + + +fn last_char_lower_current_is_upper_or_new_word(new_word: bool, last_char: char, character: char) -> bool{ + new_word || + ((last_char.is_lowercase() && character.is_uppercase()) && + (last_char != ' ')) +} + +fn char_is_seperator(character: &char) -> bool { + is_not_alphanumeric(*character) +} + +fn trim_right(convertable_string: &str) -> &str { + convertable_string.trim_end_matches(is_not_alphanumeric) +} + +fn is_not_alphanumeric(character: char) -> bool { + !character.is_alphanumeric() +} + +#[inline] +fn requires_seperator(char_with_index: (usize, char), first_character: bool, convertable_string: &str) -> bool { + !first_character && + char_is_uppercase(char_with_index.1) && + next_or_previous_char_is_lowercase(convertable_string, char_with_index.0) +} + +#[inline] +fn snake_like_no_seperator(mut accumlator: String, current_char: &char, case: &str) -> String { + if case == "lower" { + accumlator.push(current_char.to_ascii_lowercase()); + accumlator + } else { + accumlator.push(current_char.to_ascii_uppercase()); + accumlator + } +} + +#[inline] +fn snake_like_with_seperator(mut accumlator: String, replace_with: &str, current_char: &char, case: &str) -> String { + if case == "lower" { + accumlator.push(replace_with.chars().nth(0).unwrap_or('_')); + accumlator.push(current_char.to_ascii_lowercase()); + accumlator + } else { + accumlator.push(replace_with.chars().nth(0).unwrap_or('_')); + accumlator.push(current_char.to_ascii_uppercase()); + accumlator + } +} + +fn next_or_previous_char_is_lowercase(convertable_string: &str, char_with_index: usize) -> bool { + convertable_string.chars().nth(char_with_index + 1).unwrap_or('A').is_lowercase() || + convertable_string.chars().nth(char_with_index - 1).unwrap_or('A').is_lowercase() +} + +fn char_is_uppercase(test_char: char) -> bool { + test_char == test_char.to_ascii_uppercase() +} + +#[test] +fn test_trim_bad_chars() { + assert_eq!("abc", trim_right("abc----^")) +} + +#[test] +fn test_trim_bad_chars_when_none_are_bad() { + assert_eq!("abc", trim_right("abc")) +} + +#[test] +fn test_is_not_alphanumeric_on_is_alphanumeric() { + assert!(!is_not_alphanumeric('a')) +} + +#[test] +fn test_is_not_alphanumeric_on_is_not_alphanumeric() { + assert!(is_not_alphanumeric('_')) +} + + +#[test] +fn test_char_is_uppercase_when_it_is() { + assert_eq!(char_is_uppercase('A'), true) +} + +#[test] +fn test_char_is_uppercase_when_it_is_not() { + assert_eq!(char_is_uppercase('a'), false) +} + +#[test] +fn test_next_or_previous_char_is_lowercase_true() { + assert_eq!(next_or_previous_char_is_lowercase("TestWWW", 3), true) +} + +#[test] +fn test_next_or_previous_char_is_lowercase_false() { + assert_eq!(next_or_previous_char_is_lowercase("TestWWW", 5), false) +} + +#[test] +fn snake_like_with_seperator_lowers() { + assert_eq!(snake_like_with_seperator("".to_owned(), "^", &'c', "lower"), "^c".to_string()) +} + +#[test] +fn snake_like_with_seperator_upper() { + assert_eq!(snake_like_with_seperator("".to_owned(), "^", &'c', "upper"), "^C".to_string()) +} + +#[test] +fn snake_like_no_seperator_lower() { + assert_eq!(snake_like_no_seperator("".to_owned(), &'C', "lower"), "c".to_string()) +} + +#[test] +fn snake_like_no_seperator_upper() { + assert_eq!(snake_like_no_seperator("".to_owned(), &'c', "upper"), "C".to_string()) +} + +#[test] +fn requires_seperator_upper_not_first_wrap_is_safe_current_upper() { + assert_eq!(requires_seperator((2, 'C'), false, "test"), true) +} + +#[test] +fn requires_seperator_upper_not_first_wrap_is_safe_current_lower() { + assert_eq!(requires_seperator((2, 'c'), false, "test"), false) +} + +#[test] +fn requires_seperator_upper_first_wrap_is_safe_current_upper() { + assert_eq!(requires_seperator((0, 'T'), true, "Test"), false) +} + +#[test] +fn requires_seperator_upper_first_wrap_is_safe_current_lower() { + assert_eq!(requires_seperator((0, 't'), true, "Test"), false) +} + +#[test] +fn requires_seperator_upper_first_wrap_is_safe_current_lower_next_is_too() { + assert_eq!(requires_seperator((0, 't'), true, "test"), false) +} + +#[test] +fn test_char_is_seperator_dash() { + assert_eq!(char_is_seperator(&'-'), true) +} + +#[test] +fn test_char_is_seperator_underscore() { + assert_eq!(char_is_seperator(&'_'), true) +} + +#[test] +fn test_char_is_seperator_space() { + assert_eq!(char_is_seperator(&' '), true) +} + +#[test] +fn test_char_is_seperator_when_not() { + assert_eq!(char_is_seperator(&'A'), false) +} + +#[test] +fn test_last_char_lower_current_is_upper_or_new_word_with_new_word() { + assert_eq!(last_char_lower_current_is_upper_or_new_word(true, ' ', '-'), true) +} + +#[test] +fn test_last_char_lower_current_is_upper_or_new_word_last_char_space() { + assert_eq!(last_char_lower_current_is_upper_or_new_word(false, ' ', '-'), false) +} + +#[test] +fn test_last_char_lower_current_is_upper_or_new_word_last_char_lower_current_upper() { + assert_eq!(last_char_lower_current_is_upper_or_new_word(false, 'a', 'A'), true) +} + +#[test] +fn test_last_char_lower_current_is_upper_or_new_word_last_char_upper_current_upper() { + assert_eq!(last_char_lower_current_is_upper_or_new_word(false, 'A', 'A'), false) +} + +#[test] +fn test_last_char_lower_current_is_upper_or_new_word_last_char_upper_current_lower() { + assert_eq!(last_char_lower_current_is_upper_or_new_word(false, 'A', 'a'), false) +} + +#[test] +fn test_first_word_or_not_inverted_with_first_word() { + assert_eq!(first_word_or_not_inverted(true, false), true) +} + +#[test] +fn test_first_word_or_not_inverted_not_first_word_not_inverted() { + assert_eq!(first_word_or_not_inverted(false, false), true) +} + +#[test] +fn test_first_word_or_not_inverted_not_first_word_is_inverted() { + assert_eq!(first_word_or_not_inverted(false, true), false) +} + +#[test] +fn test_not_first_word_and_has_seperator_is_first_and_not_seperator() { + assert_eq!(not_first_word_and_has_seperator(true, false), false) +} + +#[test] +fn test_not_first_word_and_has_seperator_not_first_and_not_seperator() { + assert_eq!(not_first_word_and_has_seperator(false, false), false) +} + +#[test] +fn test_not_first_word_and_has_seperator_not_first_and_has_seperator() { + assert_eq!(not_first_word_and_has_seperator(false, true), true) +} diff --git a/third_party/rust/Inflector/src/cases/classcase/mod.rs b/third_party/rust/Inflector/src/cases/classcase/mod.rs new file mode 100644 index 0000000000..e0b6ef6f48 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/classcase/mod.rs @@ -0,0 +1,393 @@ +#![deny(warnings)] +use cases::case::*; +#[cfg(feature = "heavyweight")] +use string::singularize::to_singular; +#[cfg(feature = "heavyweight")] +/// Converts a `&str` to `ClassCase` `String` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "FooBars"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "foo_bars"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::to_class_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_class_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_class_case(non_class_case_string: &str) -> String { + let options = CamelOptions { + new_word: true, + last_char: ' ', + first_word: false, + injectable_char: ' ', + has_seperator: false, + inverted: false, + }; + let class_plural = to_case_camel_like(non_class_case_string, options); + let split: (&str, &str) = + class_plural.split_at(class_plural.rfind(char::is_uppercase).unwrap_or(0)); + format!("{}{}", split.0, to_singular(split.1)) +} + +#[cfg(feature = "heavyweight")] +/// Determines if a `&str` is `ClassCase` `bool` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "Foo"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "foo"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongStrings"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "foo_bar_is_a_really_really_long_strings"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::classcase::is_class_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_class_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +pub fn is_class_case(test_string: &str) -> bool { + to_class_case(&test_string.clone()) == test_string +} + +#[cfg(all(feature = "unstable", test))] +#[cfg(feature = "heavyweight")] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_class_case(b: &mut Bencher) { + b.iter(|| super::to_class_case("Foo bar")); + } + + #[bench] + fn bench_is_class(b: &mut Bencher) { + b.iter(|| super::is_class_case("Foo bar")); + } + + #[bench] + fn bench_class_from_snake(b: &mut Bencher) { + b.iter(|| super::to_class_case("foo_bar")); + } +} + +#[cfg(test)] +#[cfg(feature = "heavyweight")] +mod tests { + use ::to_class_case; + use ::is_class_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_class_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_table_case() { + let convertable_string: String = "foo_bars".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "RobertCMartin".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "RandomTextWithBadChar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "TrailingBadChar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "LeadingBadChar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "WrappedInBadChar".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "HasASign".to_owned(); + assert_eq!(to_class_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_class_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_class_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_class_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_table_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_class_case(&convertable_string), true) + } +} + diff --git a/third_party/rust/Inflector/src/cases/kebabcase/mod.rs b/third_party/rust/Inflector/src/cases/kebabcase/mod.rs new file mode 100644 index 0000000000..d79f27362a --- /dev/null +++ b/third_party/rust/Inflector/src/cases/kebabcase/mod.rs @@ -0,0 +1,262 @@ +#![deny(warnings)] +use cases::case::*; +/// Determines if a `&str` is `kebab-case` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::is_kebab_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_kebab_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +pub fn is_kebab_case(test_string: &str) -> bool { + test_string == to_kebab_case(test_string.clone()) +} + +/// Converts a `&str` to `kebab-case` `String` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::kebabcase::to_kebab_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "foo-bar".to_string(); +/// let asserted_string: String = to_kebab_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_kebab_case(non_kebab_case_string: &str) -> String { + to_case_snake_like(non_kebab_case_string, "-", "lower") +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_kebab(b: &mut Bencher) { + b.iter(|| super::to_kebab_case("Foo bar")); + } + + #[bench] + fn bench_is_kebab(b: &mut Bencher) { + b.iter(|| super::is_kebab_case("Foo bar")); + } + + #[bench] + fn bench_kebab_from_snake(b: &mut Bencher) { + b.iter(|| super::to_kebab_case("test_test_test")); + } +} + +#[cfg(test)] +mod tests { + use ::to_kebab_case; + use ::is_kebab_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "foo-bar".to_owned(); + assert_eq!(to_kebab_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_kebab_case(&convertable_string), false) + } +} + diff --git a/third_party/rust/Inflector/src/cases/mod.rs b/third_party/rust/Inflector/src/cases/mod.rs new file mode 100644 index 0000000000..dfa772e801 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/mod.rs @@ -0,0 +1,52 @@ +mod case; +/// Provides conversion to and detection of class case strings. +/// +/// This version singularizes strings. +/// +/// Example string `ClassCase` +pub mod classcase; + +/// Provides conversion to and detection of camel case strings. +/// +/// Example string `camelCase` +pub mod camelcase; + +/// Provides conversion to and detection of snake case strings. +/// +/// Example string `snake_case` +pub mod snakecase; + +/// Provides conversion to and detection of screaming snake case strings. +/// +/// Example string `SCREAMING_SNAKE_CASE` +pub mod screamingsnakecase; + +/// Provides conversion to and detection of kebab case strings. +/// +/// Example string `kebab-case` +pub mod kebabcase; + +/// Provides conversion to and detection of train case strings. +/// +/// Example string `Train-Case` +pub mod traincase; + +/// Provides conversion to and detection of sentence case strings. +/// +/// Example string `Sentence case` +pub mod sentencecase; + +/// Provides conversion to and detection of title case strings. +/// +/// Example string `Title Case` +pub mod titlecase; + +/// Provides conversion to and detection of table case strings. +/// +/// Example string `table_cases` +pub mod tablecase; + +/// Provides conversion to pascal case strings. +/// +/// Example string `PascalCase` +pub mod pascalcase; diff --git a/third_party/rust/Inflector/src/cases/pascalcase/mod.rs b/third_party/rust/Inflector/src/cases/pascalcase/mod.rs new file mode 100644 index 0000000000..248f91ab43 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/pascalcase/mod.rs @@ -0,0 +1,360 @@ +#![deny(warnings)] +use cases::case::*; +/// Converts a `&str` to pascalCase `String` +/// +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "FooBar".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::to_pascal_case; +/// let mock_string: &str = "FooBar3"; +/// let expected_string: String = "FooBar3".to_string(); +/// let asserted_string: String = to_pascal_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_pascal_case(non_pascalized_string: &str) -> String { + let options = CamelOptions { + new_word: true, + last_char: ' ', + first_word: false, + injectable_char: ' ', + has_seperator: false, + inverted: false, + }; + to_case_camel_like(non_pascalized_string, options) +} + +/// Determines if a `&str` is pascalCase bool`` +/// +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "Foo"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "foo"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "FooBarIsAReallyReally3LongString"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// +/// ``` +/// ``` +/// use inflector::cases::pascalcase::is_pascal_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_pascal_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +pub fn is_pascal_case(test_string: &str) -> bool { + to_pascal_case(test_string.clone()) == test_string +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_pascal0(b: &mut Bencher) { + b.iter(|| { + let test_string = "Foo bar"; + super::to_pascal_case(test_string) + }); + } + + #[bench] + fn bench_pascal1(b: &mut Bencher) { + b.iter(|| { + let test_string = "foo_bar"; + super::to_pascal_case(test_string) + }); + } + + #[bench] + fn bench_pascal2(b: &mut Bencher) { + b.iter(|| { + let test_string = "fooBar"; + super::to_pascal_case(test_string) + }); + } + + #[bench] + fn bench_is_pascal(b: &mut Bencher) { + b.iter(|| { + let test_string: &str = "Foo bar"; + super::is_pascal_case(test_string) + }); + } +} + +#[cfg(test)] +mod tests { + use ::to_pascal_case; + use ::is_pascal_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "FooBar".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "RobertCMartin".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "RandomTextWithBadChars".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "TrailingBadChars".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "LeadingBadChars".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "WrappedInBadChars".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "HasASign".to_owned(); + assert_eq!(to_pascal_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_pascal_case(&convertable_string), false) + } +} diff --git a/third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs b/third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs new file mode 100644 index 0000000000..9bec7a5536 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs @@ -0,0 +1,253 @@ +#![deny(warnings)] +use cases::case::*; +/// Converts a `&str` to `SCREAMING_SNAKE_CASE` `String` +/// +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "FOO_BAR".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "HTTP Foo bar"; +/// let expected_string: String = "HTTP_FOO_BAR".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "FOO_BAR".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "FOO_BAR".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "FOO_BAR".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "FOO_BAR".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; +/// let mock_string: &str = "fooBar3"; +/// let expected_string: String = "FOO_BAR_3".to_string(); +/// let asserted_string: String = to_screaming_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_screaming_snake_case(non_snake_case_string: &str) -> String { + to_case_snake_like(non_snake_case_string, "_", "upper") +} + +/// Determines of a `&str` is `SCREAMING_SNAKE_CASE` +/// +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "FOO_BAR1_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// ``` +/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; +/// let mock_string: &str = "FOO_BAR_1_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_screaming_snake_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +pub fn is_screaming_snake_case(test_string: &str) -> bool { + test_string == to_screaming_snake_case(test_string.clone()) +} + + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_screaming_snake(b: &mut Bencher) { + b.iter(|| super::to_screaming_snake_case("Foo bar")); + } + + #[bench] + fn bench_is_screaming_snake(b: &mut Bencher) { + b.iter(|| super::is_screaming_snake_case("Foo bar")); + } + +} + +#[cfg(test)] +mod tests { + use ::to_screaming_snake_case; + use ::is_screaming_snake_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "FOO_BAR".to_owned(); + assert_eq!(to_screaming_snake_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_screaming_snake_case(&convertable_string), false) + } +} diff --git a/third_party/rust/Inflector/src/cases/sentencecase/mod.rs b/third_party/rust/Inflector/src/cases/sentencecase/mod.rs new file mode 100644 index 0000000000..5a99d217f4 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/sentencecase/mod.rs @@ -0,0 +1,313 @@ +#![deny(warnings)] +use cases::case::*; +/// Converts a `&str` to `Sentence case` `String` +/// +/// ``` +/// use inflector::cases::sentencecase::to_sentence_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "Foo bar".to_string(); +/// let asserted_string: String = to_sentence_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::to_sentence_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "Foo bar".to_string(); +/// let asserted_string: String = to_sentence_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::to_sentence_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "Foo bar".to_string(); +/// let asserted_string: String = to_sentence_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::to_sentence_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "Foo bar".to_string(); +/// let asserted_string: String = to_sentence_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::to_sentence_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "Foo bar".to_string(); +/// let asserted_string: String = to_sentence_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::to_sentence_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "Foo bar".to_string(); +/// let asserted_string: String = to_sentence_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_sentence_case(non_sentence_case_string: &str) -> String { + let options = CamelOptions { + new_word: true, + last_char: ' ', + first_word: true, + injectable_char: ' ', + has_seperator: true, + inverted: true, + }; + to_case_camel_like(non_sentence_case_string, options) +} +/// Determines of a `&str` is `Sentence case` +/// +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "Foo"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "foo"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::sentencecase::is_sentence_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_sentence_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +pub fn is_sentence_case(test_string: &str) -> bool { + test_string == to_sentence_case(test_string.clone()) +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_sentence(b: &mut Bencher) { + b.iter(|| super::to_sentence_case("Foo BAR")); + } + + #[bench] + fn bench_is_sentence(b: &mut Bencher) { + b.iter(|| super::is_sentence_case("Foo bar")); + } + + #[bench] + fn bench_sentence_from_snake(b: &mut Bencher) { + b.iter(|| super::to_sentence_case("foo_bar")); + } + +} + +#[cfg(test)] +mod tests { + use ::to_sentence_case; + use ::is_sentence_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "Foo bar".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "Robert c martin".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "Random text with bad chars".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "Trailing bad chars".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "Leading bad chars".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "Wrapped in bad chars".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "Has a sign".to_owned(); + assert_eq!(to_sentence_case(&convertable_string), expected) + } + + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_sentence_case(&convertable_string), false) + } +} diff --git a/third_party/rust/Inflector/src/cases/snakecase/mod.rs b/third_party/rust/Inflector/src/cases/snakecase/mod.rs new file mode 100644 index 0000000000..a56894b1a1 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/snakecase/mod.rs @@ -0,0 +1,334 @@ +#![deny(warnings)] +use cases::case::*; +/// Converts a `&str` to `snake_case` `String` +/// +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "HTTP Foo bar"; +/// let expected_string: String = "http_foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "HTTPFooBar"; +/// let expected_string: String = "http_foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "foo_bar".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::to_snake_case; +/// let mock_string: &str = "fooBar3"; +/// let expected_string: String = "foo_bar_3".to_string(); +/// let asserted_string: String = to_snake_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_snake_case(non_snake_case_string: &str) -> String { + to_case_snake_like(non_snake_case_string, "_", "lower") +} + +/// Determines of a `&str` is `snake_case` +/// +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "FOO_BAR_IS_A_REALLY_REALLY_LONG_STRING"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "foo_bar1_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::snakecase::is_snake_case; +/// let mock_string: &str = "foo_bar_1_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_snake_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +pub fn is_snake_case(test_string: &str) -> bool { + test_string == to_snake_case(test_string.clone()) +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_snake_from_title(b: &mut Bencher) { + b.iter(|| super::to_snake_case("Foo bar")); + } + + #[bench] + fn bench_snake_from_camel(b: &mut Bencher) { + b.iter(|| super::to_snake_case("fooBar")); + } + + #[bench] + fn bench_snake_from_snake(b: &mut Bencher) { + b.iter(|| super::to_snake_case("foo_bar_bar_bar")); + } + + #[bench] + fn bench_is_snake(b: &mut Bencher) { + b.iter(|| super::is_snake_case("Foo bar")); + } + +} + +#[cfg(test)] +mod tests { + use ::to_snake_case; + use ::is_snake_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "foo_bar".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "robert_c_martin".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "random_text_with_bad_chars".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "trailing_bad_chars".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "leading_bad_chars".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "wrapped_in_bad_chars".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "has_a_sign".to_owned(); + assert_eq!(to_snake_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_snake_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_snake_case(&convertable_string), true) + } +} diff --git a/third_party/rust/Inflector/src/cases/tablecase/mod.rs b/third_party/rust/Inflector/src/cases/tablecase/mod.rs new file mode 100644 index 0000000000..7224cc439b --- /dev/null +++ b/third_party/rust/Inflector/src/cases/tablecase/mod.rs @@ -0,0 +1,271 @@ +#![deny(warnings)] +#[cfg(feature = "heavyweight")] +use string::pluralize::to_plural; +#[cfg(feature = "heavyweight")] +use cases::case::*; +#[cfg(feature = "heavyweight")] +/// Converts a `&str` to `table-case` `String` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::to_table_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "foo_bars".to_string(); +/// let asserted_string: String = to_table_case(mock_string); +/// assert!(asserted_string == expected_string); +/// ``` +pub fn to_table_case(non_table_case_string: &str) -> String { + let snaked: String = to_case_snake_like(non_table_case_string, "_", "lower"); + let split: (&str, &str) = snaked.split_at(snaked.rfind('_').unwrap_or(0)); + format!("{}{}", split.0, to_plural(split.1)) +} + +#[cfg(feature = "heavyweight")] +/// Determines if a `&str` is `table-case` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "foo_bar_strings"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == true); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +/// +/// ``` +/// use inflector::cases::tablecase::is_table_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_table_case(mock_string); +/// assert!(asserted_bool == false); +/// ``` +pub fn is_table_case(test_string: &str) -> bool { + to_table_case(&test_string.clone()) == test_string +} + +#[cfg(all(feature = "unstable", test))] +#[cfg(feature = "heavyweight")] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_table_case(b: &mut Bencher) { + b.iter(|| super::to_table_case("Foo bar")); + } + + #[bench] + fn bench_is_table_case(b: &mut Bencher) { + b.iter(|| super::is_table_case("Foo bar")); + } +} + +#[cfg(test)] +#[cfg(feature = "heavyweight")] +mod tests { + use ::to_table_case; + use ::is_table_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn from_table_case() { + let convertable_string: String = "foo_bars".to_owned(); + let expected: String = "foo_bars".to_owned(); + assert_eq!(to_table_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_table_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_table_case() { + let convertable_string: String = "foo_bars".to_owned(); + assert_eq!(is_table_case(&convertable_string), true) + } +} diff --git a/third_party/rust/Inflector/src/cases/titlecase/mod.rs b/third_party/rust/Inflector/src/cases/titlecase/mod.rs new file mode 100644 index 0000000000..eb0de25744 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/titlecase/mod.rs @@ -0,0 +1,308 @@ +#![deny(warnings)] +use cases::case::*; +/// Converts a `&str` to `Title Case` `String` +/// +/// ``` +/// use inflector::cases::titlecase::to_title_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "Foo Bar".to_string(); +/// let asserted_string: String = to_title_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::to_title_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "Foo Bar".to_string(); +/// let asserted_string: String = to_title_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::to_title_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "Foo Bar".to_string(); +/// let asserted_string: String = to_title_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::to_title_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "Foo Bar".to_string(); +/// let asserted_string: String = to_title_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::to_title_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "Foo Bar".to_string(); +/// let asserted_string: String = to_title_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::to_title_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "Foo Bar".to_string(); +/// let asserted_string: String = to_title_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_title_case(non_title_case_string: &str) -> String { + let options = CamelOptions { + new_word: true, + last_char: ' ', + first_word: true, + injectable_char: ' ', + has_seperator: true, + inverted: false, + }; + to_case_camel_like(non_title_case_string, options) +} + +/// Determines if a `&str` is `Title Case` +/// +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "foo"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::cases::titlecase::is_title_case; +/// let mock_string: &str = "Foo Bar String That Is Really Really Long"; +/// let asserted_bool: bool = is_title_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +pub fn is_title_case(test_string: &str) -> bool { + test_string == to_title_case(test_string.clone()) +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_title(b: &mut Bencher) { + b.iter(|| super::to_title_case("Foo BAR")); + } + + #[bench] + fn bench_is_title(b: &mut Bencher) { + b.iter(|| super::is_title_case("Foo bar")); + } + + #[bench] + fn bench_title_from_snake(b: &mut Bencher) { + b.iter(|| super::to_title_case("foo_bar")); + } + +} + + +#[cfg(test)] +mod tests { + use ::to_title_case; + use ::is_title_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "Foo Bar".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "Robert C Martin".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "Random Text With Bad Chars".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "Trailing Bad Chars".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "Leading Bad Chars".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "Wrapped In Bad Chars".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "Has A Sign".to_owned(); + assert_eq!(to_title_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_title_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_title_case(&convertable_string), false) + } +} + diff --git a/third_party/rust/Inflector/src/cases/traincase/mod.rs b/third_party/rust/Inflector/src/cases/traincase/mod.rs new file mode 100644 index 0000000000..cb2e882818 --- /dev/null +++ b/third_party/rust/Inflector/src/cases/traincase/mod.rs @@ -0,0 +1,320 @@ +#![deny(warnings)] +use cases::case::*; +/// Determines if a `&str` is `Train-Case` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "Foo-Bar-String-That-Is-Really-Really-Long"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::is_train_case; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_train_case(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +pub fn is_train_case(test_string: &str) -> bool { + test_string == to_train_case(test_string.clone()) +} + + +/// Converts a `&str` to `Train-Case` `String` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "foo-bar"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "FOO_BAR"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +/// ``` +/// use inflector::cases::traincase::to_train_case; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "Foo-Bar".to_string(); +/// let asserted_string: String = to_train_case(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_train_case(non_train_case_string: &str) -> String { + let options = CamelOptions { + new_word: true, + last_char: ' ', + first_word: true, + injectable_char: '-', + has_seperator: true, + inverted: false, + }; + to_case_camel_like(non_train_case_string, options) +} + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_train(b: &mut Bencher) { + b.iter(|| super::to_train_case("Foo bar")); + } + + #[bench] + fn bench_is_train(b: &mut Bencher) { + b.iter(|| super::is_train_case("Foo bar")); + } + + #[bench] + fn bench_train_from_snake(b: &mut Bencher) { + b.iter(|| super::to_train_case("test_test_test")); + } + +} + +#[cfg(test)] +mod tests { + use ::to_train_case; + use ::is_train_case; + + #[test] + fn from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn from_case_with_loads_of_space() { + let convertable_string: String = "foo bar".to_owned(); + let expected: String = "Foo-Bar".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn a_name_with_a_dot() { + let convertable_string: String = "Robert C. Martin".to_owned(); + let expected: String = "Robert-C-Martin".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn random_text_with_bad_chars() { + let convertable_string: String = "Random text with *(bad) chars".to_owned(); + let expected: String = "Random-Text-With-Bad-Chars".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn trailing_bad_chars() { + let convertable_string: String = "trailing bad_chars*(()())".to_owned(); + let expected: String = "Trailing-Bad-Chars".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn leading_bad_chars() { + let convertable_string: String = "-!#$%leading bad chars".to_owned(); + let expected: String = "Leading-Bad-Chars".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn wrapped_in_bad_chars() { + let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<><?>><?><>))".to_owned(); + let expected: String = "Wrapped-In-Bad-Chars".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn has_a_sign() { + let convertable_string: String = "has a + sign".to_owned(); + let expected: String = "Has-A-Sign".to_owned(); + assert_eq!(to_train_case(&convertable_string), expected) + } + + #[test] + fn is_correct_from_camel_case() { + let convertable_string: String = "fooBar".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_pascal_case() { + let convertable_string: String = "FooBar".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_kebab_case() { + let convertable_string: String = "foo-bar".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_sentence_case() { + let convertable_string: String = "Foo bar".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_title_case() { + let convertable_string: String = "Foo Bar".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_train_case() { + let convertable_string: String = "Foo-Bar".to_owned(); + assert_eq!(is_train_case(&convertable_string), true) + } + + #[test] + fn is_correct_from_screaming_snake_case() { + let convertable_string: String = "FOO_BAR".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } + + #[test] + fn is_correct_from_snake_case() { + let convertable_string: String = "foo_bar".to_owned(); + assert_eq!(is_train_case(&convertable_string), false) + } +} diff --git a/third_party/rust/Inflector/src/lib.rs b/third_party/rust/Inflector/src/lib.rs new file mode 100644 index 0000000000..f52ea29f40 --- /dev/null +++ b/third_party/rust/Inflector/src/lib.rs @@ -0,0 +1,332 @@ +#![deny(warnings, unused_variables, missing_docs, unsafe_code, unused_extern_crates)] +#![cfg_attr(feature = "unstable", feature(test))] + +//! Adds String based inflections for Rust. Snake, kebab, train, camel, +//! sentence, class, and title cases as well as ordinalize, +//! deordinalize, demodulize, deconstantize, and foreign key are supported as +//! both traits and pure functions acting on String types. +//! ```rust +//! use inflector::Inflector; +//! let camel_case_string: String = "some_string".to_camel_case(); +//! let is_camel_cased: bool= camel_case_string.is_camel_case(); +//! assert!(is_camel_cased == true); +//! ``` + +#[cfg(feature = "heavyweight")] +extern crate regex; + +#[cfg(feature = "heavyweight")] +#[macro_use] extern crate lazy_static; + +/// Provides case inflections +/// - Camel case +/// - Class case +/// - Kebab case +/// - Train case +/// - Screaming snake case +/// - Table case +/// - Sentence case +/// - Snake case +/// - Pascal case +pub mod cases; +/// Provides number inflections +/// - Ordinalize +/// - Deordinalize +pub mod numbers; +/// Provides suffix inflections +/// - Foreign key +pub mod suffix; +/// Provides string inflections +/// - Deconstantize +/// - Demodulize +/// - Pluralize +/// - Singularize +#[cfg(feature = "heavyweight")] +pub mod string; + + +#[cfg(feature = "heavyweight")] +use cases::classcase::to_class_case; +#[cfg(feature = "heavyweight")] +use cases::classcase::is_class_case; + +use cases::camelcase::to_camel_case; +use cases::camelcase::is_camel_case; + +use cases::pascalcase::to_pascal_case; +use cases::pascalcase::is_pascal_case; + +use cases::snakecase::to_snake_case; +use cases::snakecase::is_snake_case; + +use cases::screamingsnakecase::to_screaming_snake_case; +use cases::screamingsnakecase::is_screaming_snake_case; + +use cases::kebabcase::to_kebab_case; +use cases::kebabcase::is_kebab_case; + +use cases::traincase::to_train_case; +use cases::traincase::is_train_case; + +use cases::sentencecase::to_sentence_case; +use cases::sentencecase::is_sentence_case; + +use cases::titlecase::to_title_case; +use cases::titlecase::is_title_case; + +#[cfg(feature = "heavyweight")] +use cases::tablecase::to_table_case; +#[cfg(feature = "heavyweight")] +use cases::tablecase::is_table_case; + +use numbers::ordinalize::ordinalize; +use numbers::deordinalize::deordinalize; + +use suffix::foreignkey::to_foreign_key; +use suffix::foreignkey::is_foreign_key; + +#[cfg(feature = "heavyweight")] +use string::demodulize::demodulize; +#[cfg(feature = "heavyweight")] +use string::deconstantize::deconstantize; + +#[cfg(feature = "heavyweight")] +use string::pluralize::to_plural; +#[cfg(feature = "heavyweight")] +use string::singularize::to_singular; + +#[allow(missing_docs)] +pub trait Inflector { + + fn to_camel_case(&self) -> String; + fn is_camel_case(&self) -> bool; + + fn to_pascal_case(&self) -> String; + fn is_pascal_case(&self) -> bool; + + fn to_snake_case(&self) -> String; + fn is_snake_case(&self) -> bool; + + fn to_screaming_snake_case(&self) -> String; + fn is_screaming_snake_case(&self) -> bool; + + fn to_kebab_case(&self) -> String; + fn is_kebab_case(&self) -> bool; + + fn to_train_case(&self) -> String; + fn is_train_case(&self) -> bool; + + fn to_sentence_case(&self) -> String; + fn is_sentence_case(&self) -> bool; + + fn to_title_case(&self) -> String; + fn is_title_case(&self) -> bool; + + fn ordinalize(&self) -> String; + fn deordinalize(&self) -> String; + + fn to_foreign_key(&self) -> String; + fn is_foreign_key(&self) -> bool; + + #[cfg(feature = "heavyweight")] + fn demodulize(&self) -> String; + #[cfg(feature = "heavyweight")] + fn deconstantize(&self) -> String; + + #[cfg(feature = "heavyweight")] + fn to_class_case(&self) -> String; + #[cfg(feature = "heavyweight")] + fn is_class_case(&self) -> bool; + + #[cfg(feature = "heavyweight")] + fn to_table_case(&self) -> String; + #[cfg(feature = "heavyweight")] + fn is_table_case(&self) -> bool; + #[cfg(feature = "heavyweight")] + fn to_plural(&self) -> String; + #[cfg(feature = "heavyweight")] + fn to_singular(&self) -> String; +} + + +#[allow(missing_docs)] +pub trait InflectorNumbers { + fn ordinalize(&self) -> String; +} + + +macro_rules! define_implementations { + ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => { + $( + #[inline] + fn $imp_trait(&$slf) -> $typ { + $imp_trait($slf) + } + )* + } +} + +macro_rules! define_number_implementations { + ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => { + $( + #[inline] + fn $imp_trait(&$slf) -> $typ { + $imp_trait(&$slf.to_string()) + } + )* + } +} + +macro_rules! define_gated_implementations { + ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => { + $( + #[inline] + #[cfg(feature = "heavyweight")] + fn $imp_trait(&$slf) -> $typ { + $imp_trait($slf) + } + )* + } +} + +macro_rules! implement_string_for { + ( $trt:ident; $($typ:ident), *) => { + $( + impl $trt for $typ { + define_implementations![self; + to_camel_case => String, + is_camel_case => bool, + to_pascal_case => String, + is_pascal_case => bool, + to_screaming_snake_case => String, + is_screaming_snake_case => bool, + to_snake_case => String, + is_snake_case => bool, + to_kebab_case => String, + is_kebab_case => bool, + to_train_case => String, + is_train_case => bool, + to_sentence_case => String, + is_sentence_case => bool, + to_title_case => String, + is_title_case => bool, + to_foreign_key => String, + is_foreign_key => bool, + ordinalize => String, + deordinalize => String + ]; + define_gated_implementations![self; + to_class_case => String, + is_class_case => bool, + to_table_case => String, + is_table_case => bool, + to_plural => String, + to_singular => String, + demodulize => String, + deconstantize => String + ]; + } + )* + } +} + +macro_rules! implement_number_for { + ( $trt:ident; $($typ:ident), *) => { + $( + impl $trt for $typ { + define_number_implementations![self; + ordinalize => String + ]; + } + )* + } +} + +implement_string_for![ + Inflector; + String, str +]; + +implement_number_for![ + InflectorNumbers; + i8, i16, i32, i64, u8, u16, u32, u64, isize, usize, f32, f64 +]; + +#[cfg(all(feature = "unstable", test))] +mod benchmarks { + extern crate test; + use self::test::Bencher; + use ::Inflector; + + macro_rules! benchmarks { + ( $($test_name:ident => $imp_trait:ident => $to_cast:expr), *) => { + $( + #[bench] + fn $test_name(b: &mut Bencher) { + b.iter(|| { + $to_cast.$imp_trait() + }); + } + )* + } + } + + benchmarks![ + benchmark_str_to_camel => to_camel_case => "foo_bar", + benchmark_str_is_camel => is_camel_case => "fooBar", + benchmark_str_to_screaming_snake => to_screaming_snake_case => "fooBar", + benchmark_str_is_screaming_snake => is_screaming_snake_case => "FOO_BAR", + benchmark_str_to_snake => to_snake_case => "fooBar", + benchmark_str_is_snake => is_snake_case => "foo_bar", + benchmark_str_to_kebab => to_kebab_case => "fooBar", + benchmark_str_is_kebab => is_kebab_case => "foo-bar", + benchmark_str_to_train => to_train_case => "fooBar", + benchmark_str_is_train => is_train_case => "Foo-Bar", + benchmark_str_to_sentence => to_sentence_case => "fooBar", + benchmark_str_is_sentence => is_sentence_case => "Foo bar", + benchmark_str_to_title => to_title_case => "fooBar", + benchmark_str_is_title => is_title_case => "Foo Bar", + benchmark_str_ordinalize => ordinalize => "1", + benchmark_str_deordinalize => deordinalize => "1st", + benchmark_str_to_foreign_key => to_foreign_key => "Foo::Bar", + benchmark_str_is_foreign_key => is_foreign_key => "bar_id", + benchmark_string_to_camel => to_camel_case => "foo_bar".to_string(), + benchmark_string_is_camel => is_camel_case => "fooBar".to_string(), + benchmark_string_to_screaming_snake => to_screaming_snake_case => "fooBar".to_string(), + benchmark_string_is_screaming_snake => is_screaming_snake_case => "FOO_BAR".to_string(), + benchmark_string_to_snake => to_snake_case => "fooBar".to_string(), + benchmark_string_is_snake => is_snake_case => "foo_bar".to_string(), + benchmark_string_to_kebab => to_kebab_case => "fooBar".to_string(), + benchmark_string_is_kebab => is_kebab_case => "foo-bar".to_string(), + benchmark_string_to_train => to_train_case => "fooBar".to_string(), + benchmark_string_is_train => is_train_case => "Foo-Bar".to_string(), + benchmark_string_to_sentence => to_sentence_case => "fooBar".to_string(), + benchmark_string_is_sentence => is_sentence_case => "Foo bar".to_string(), + benchmark_string_to_title => to_title_case => "fooBar".to_string(), + benchmark_string_is_title => is_title_case => "Foo Bar".to_string(), + benchmark_string_ordinalize => ordinalize => "1".to_string(), + benchmark_string_deordinalize => deordinalize => "1st".to_string(), + benchmark_string_to_foreign_key => to_foreign_key => "Foo::Bar".to_string(), + benchmark_string_is_foreign_key => is_foreign_key => "bar_id".to_string() + ]; + + #[cfg(feature = "heavyweight")] + benchmarks![ + benchmark_str_to_class => to_class_case => "foo", + benchmark_str_is_class => is_class_case => "Foo", + benchmark_str_to_table => to_table_case => "fooBar", + benchmark_str_is_table => is_table_case => "foo_bars", + benchmark_str_pluralize => to_plural => "crate", + benchmark_str_singular => to_singular => "crates", + benchmark_string_to_class => to_class_case => "foo".to_string(), + benchmark_string_is_class => is_class_case => "Foo".to_string(), + benchmark_string_to_table => to_table_case => "fooBar".to_string(), + benchmark_string_is_table => is_table_case => "foo_bars".to_string(), + benchmark_string_pluralize => to_plural => "crate".to_string(), + benchmark_string_singular => to_singular => "crates".to_string(), + benchmark_string_demodulize => demodulize => "Foo::Bar".to_string(), + benchmark_string_deconstantize => deconstantize => "Foo::Bar".to_string(), + benchmark_str_demodulize => demodulize => "Foo::Bar", + benchmark_str_deconstantize => deconstantize => "Foo::Bar" + ]; +} diff --git a/third_party/rust/Inflector/src/numbers/deordinalize/mod.rs b/third_party/rust/Inflector/src/numbers/deordinalize/mod.rs new file mode 100644 index 0000000000..f64cce1143 --- /dev/null +++ b/third_party/rust/Inflector/src/numbers/deordinalize/mod.rs @@ -0,0 +1,117 @@ +/// Deorginalizes a `&str` +/// +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "0.1"; +/// let expected_string: String = "0.1".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "-1st"; +/// let expected_string: String = "-1".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "0th"; +/// let expected_string: String = "0".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "1st"; +/// let expected_string: String = "1".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "2nd"; +/// let expected_string: String = "2".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "3rd"; +/// let expected_string: String = "3".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "9th"; +/// let expected_string: String = "9".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "12th"; +/// let expected_string: String = "12".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "12000th"; +/// let expected_string: String = "12000".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "12001th"; +/// let expected_string: String = "12001".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "12002nd"; +/// let expected_string: String = "12002".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "12003rd"; +/// let expected_string: String = "12003".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::deordinalize::deordinalize; +/// let mock_string: &str = "12004th"; +/// let expected_string: String = "12004".to_owned(); +/// let asserted_string: String = deordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn deordinalize(non_ordinalized_string: &str) -> String { + if non_ordinalized_string.contains('.') { + non_ordinalized_string.to_owned() + } else { + non_ordinalized_string.trim_end_matches("st") + .trim_end_matches("nd") + .trim_end_matches("rd") + .trim_end_matches("th") + .to_owned() + } +} diff --git a/third_party/rust/Inflector/src/numbers/mod.rs b/third_party/rust/Inflector/src/numbers/mod.rs new file mode 100644 index 0000000000..f28704f52e --- /dev/null +++ b/third_party/rust/Inflector/src/numbers/mod.rs @@ -0,0 +1,9 @@ +#![deny(warnings)] +/// Provides ordinalization of a string. +/// +/// Example string "1" becomes "1st" +pub mod ordinalize; +/// Provides deordinalization of a string. +/// +/// Example string "1st" becomes "1" +pub mod deordinalize; diff --git a/third_party/rust/Inflector/src/numbers/ordinalize/mod.rs b/third_party/rust/Inflector/src/numbers/ordinalize/mod.rs new file mode 100644 index 0000000000..82b0d2d834 --- /dev/null +++ b/third_party/rust/Inflector/src/numbers/ordinalize/mod.rs @@ -0,0 +1,147 @@ +/// Orginalizes a `&str` +/// +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "a"; +/// let expected_string: String = "a".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "0.1"; +/// let expected_string: String = "0.1".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "-1"; +/// let expected_string: String = "-1st".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "0"; +/// let expected_string: String = "0th".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "1"; +/// let expected_string: String = "1st".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "2"; +/// let expected_string: String = "2nd".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "3"; +/// let expected_string: String = "3rd".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "9"; +/// let expected_string: String = "9th".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "12"; +/// let expected_string: String = "12th".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "12000"; +/// let expected_string: String = "12000th".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "12001"; +/// let expected_string: String = "12001st".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "12002"; +/// let expected_string: String = "12002nd".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "12003"; +/// let expected_string: String = "12003rd".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::numbers::ordinalize::ordinalize; +/// let mock_string: &str = "12004"; +/// let expected_string: String = "12004th".to_owned(); +/// let asserted_string: String = ordinalize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn ordinalize(non_ordinalized_string: &str) -> String { + let chars: Vec<char> = non_ordinalized_string.clone().chars().collect(); + let last_number: char = chars[chars.len() - 1]; + if is_ordinalizable(last_number) { + return non_ordinalized_string.to_owned(); + } + if chars.len() > 1 { + if second_last_number_is_one(chars) { + return format!("{}{}", non_ordinalized_string, "th"); + } else if string_contains_decimal(non_ordinalized_string.to_owned()) { + return non_ordinalized_string.to_owned(); + } + } + match last_number { + '1' => format!("{}{}", non_ordinalized_string, "st"), + '2' => format!("{}{}", non_ordinalized_string, "nd"), + '3' => format!("{}{}", non_ordinalized_string, "rd"), + _ => format!("{}{}", non_ordinalized_string, "th"), + } +} + +fn is_ordinalizable(last_number: char) -> bool { + !last_number.is_numeric() +} + +fn second_last_number_is_one(chars: Vec<char>) -> bool { + let second_last_number: char = chars[chars.len() - 2]; + second_last_number == '1' +} + +fn string_contains_decimal(non_ordinalized_string: String) -> bool { + non_ordinalized_string.contains('.') +} diff --git a/third_party/rust/Inflector/src/string/constants/mod.rs b/third_party/rust/Inflector/src/string/constants/mod.rs new file mode 100644 index 0000000000..0ba4e429f9 --- /dev/null +++ b/third_party/rust/Inflector/src/string/constants/mod.rs @@ -0,0 +1,225 @@ +pub const UNACCONTABLE_WORDS: [&'static str; 202] = ["accommodation", + "adulthood", + "advertising", + "advice", + "aggression", + "aid", + "air", + "aircraft", + "alcohol", + "anger", + "applause", + "arithmetic", + "assistance", + "athletics", + + "bacon", + "baggage", + "beef", + "biology", + "blood", + "botany", + "bread", + "butter", + + "carbon", + "cardboard", + "cash", + "chalk", + "chaos", + "chess", + "crossroads", + "countryside", + + "dancing", + "deer", + "dignity", + "dirt", + "dust", + + "economics", + "education", + "electricity", + "engineering", + "enjoyment", + "envy", + "equipment", + "ethics", + "evidence", + "evolution", + + "fame", + "fiction", + "flour", + "flu", + "food", + "fuel", + "fun", + "furniture", + + "gallows", + "garbage", + "garlic", + "genetics", + "gold", + "golf", + "gossip", + "grammar", + "gratitude", + "grief", + "guilt", + "gymnastics", + + "happiness", + "hardware", + "harm", + "hate", + "hatred", + "health", + "heat", + "help", + "homework", + "honesty", + "honey", + "hospitality", + "housework", + "humour", + "hunger", + "hydrogen", + + "ice", + "importance", + "inflation", + "information", + "innocence", + "iron", + "irony", + + "jam", + "jewelry", + "judo", + + "karate", + "knowledge", + + "lack", + "laughter", + "lava", + "leather", + "leisure", + "lightning", + "linguine", + "linguini", + "linguistics", + "literature", + "litter", + "livestock", + "logic", + "loneliness", + "luck", + "luggage", + + "macaroni", + "machinery", + "magic", + "management", + "mankind", + "marble", + "mathematics", + "mayonnaise", + "measles", + "methane", + "milk", + "money", + "mud", + "music", + "mumps", + + "nature", + "news", + "nitrogen", + "nonsense", + "nurture", + "nutrition", + + "obedience", + "obesity", + "oxygen", + + "pasta", + "patience", + "physics", + "poetry", + "pollution", + "poverty", + "pride", + "psychology", + "publicity", + "punctuation", + + "quartz", + + "racism", + "relaxation", + "reliability", + "research", + "respect", + "revenge", + "rice", + "rubbish", + "rum", + + "safety", + "scenery", + "seafood", + "seaside", + "series", + "shame", + "sheep", + "shopping", + "sleep", + "smoke", + "smoking", + "snow", + "soap", + "software", + "soil", + "spaghetti", + "species", + "steam", + "stuff", + "stupidity", + "sunshine", + "symmetry", + + "tennis", + "thirst", + "thunder", + "timber", + "traffic", + "transportation", + "trust", + + "underwear", + "unemployment", + "unity", + + "validity", + "veal", + "vegetation", + "vegetarianism", + "vengeance", + "violence", + "vitality", + + "warmth", + "wealth", + "weather", + "welfare", + "wheat", + "wildlife", + "wisdom", + "yoga", + + "zinc", + "zoology"]; diff --git a/third_party/rust/Inflector/src/string/deconstantize/mod.rs b/third_party/rust/Inflector/src/string/deconstantize/mod.rs new file mode 100644 index 0000000000..5b106e5655 --- /dev/null +++ b/third_party/rust/Inflector/src/string/deconstantize/mod.rs @@ -0,0 +1,50 @@ +#[cfg(feature = "heavyweight")] +use cases::classcase::to_class_case; + +#[cfg(feature = "heavyweight")] +/// Deconstantizes a `&str` +/// +/// ``` +/// use inflector::string::deconstantize::deconstantize; +/// let mock_string: &str = "Bar"; +/// let expected_string: String = "".to_owned(); +/// let asserted_string: String = deconstantize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::deconstantize::deconstantize; +/// let mock_string: &str = "::Bar"; +/// let expected_string: String = "".to_owned(); +/// let asserted_string: String = deconstantize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::deconstantize::deconstantize; +/// let mock_string: &str = "Foo::Bar"; +/// let expected_string: String = "Foo".to_owned(); +/// let asserted_string: String = deconstantize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::deconstantize::deconstantize; +/// let mock_string: &str = "Test::Foo::Bar"; +/// let expected_string: String = "Foo".to_owned(); +/// let asserted_string: String = deconstantize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn deconstantize(non_deconstantized_string: &str) -> String { + if non_deconstantized_string.contains("::") { + let split_string: Vec<&str> = non_deconstantized_string.split("::").collect(); + if split_string.len() > 1 { + to_class_case(split_string[split_string.len() - 2]) + } else { + "".to_owned() + } + } else { + "".to_owned() + } +} diff --git a/third_party/rust/Inflector/src/string/demodulize/mod.rs b/third_party/rust/Inflector/src/string/demodulize/mod.rs new file mode 100644 index 0000000000..5d4bd77168 --- /dev/null +++ b/third_party/rust/Inflector/src/string/demodulize/mod.rs @@ -0,0 +1,46 @@ +#[cfg(feature = "heavyweight")] +use cases::classcase::to_class_case; + +#[cfg(feature = "heavyweight")] +/// Demodulize a `&str` +/// +/// ``` +/// use inflector::string::demodulize::demodulize; +/// let mock_string: &str = "Bar"; +/// let expected_string: String = "Bar".to_owned(); +/// let asserted_string: String = demodulize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::demodulize::demodulize; +/// let mock_string: &str = "::Bar"; +/// let expected_string: String = "Bar".to_owned(); +/// let asserted_string: String = demodulize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::demodulize::demodulize; +/// let mock_string: &str = "Foo::Bar"; +/// let expected_string: String = "Bar".to_owned(); +/// let asserted_string: String = demodulize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::demodulize::demodulize; +/// let mock_string: &str = "Test::Foo::Bar"; +/// let expected_string: String = "Bar".to_owned(); +/// let asserted_string: String = demodulize(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn demodulize(non_demodulize_string: &str) -> String { + if non_demodulize_string.contains("::") { + let split_string: Vec<&str> = non_demodulize_string.split("::").collect(); + to_class_case(split_string[split_string.len() - 1]) + } else { + non_demodulize_string.to_owned() + } +} diff --git a/third_party/rust/Inflector/src/string/mod.rs b/third_party/rust/Inflector/src/string/mod.rs new file mode 100644 index 0000000000..72702881d3 --- /dev/null +++ b/third_party/rust/Inflector/src/string/mod.rs @@ -0,0 +1,23 @@ +#![deny(warnings)] +/// Provides demodulize a string. +/// +/// Example string `Foo::Bar` becomes `Bar` +#[cfg(feature = "heavyweight")] +pub mod demodulize; +/// Provides deconstantizea string. +/// +/// Example string `Foo::Bar` becomes `Foo` +#[cfg(feature = "heavyweight")] +pub mod deconstantize; +/// Provides conversion to plural strings. +/// +/// Example string `FooBar` -> `FooBars` +#[cfg(feature = "heavyweight")] +pub mod pluralize; +/// Provides conversion to singular strings. +/// +/// Example string `FooBars` -> `FooBar` +#[cfg(feature = "heavyweight")] +pub mod singularize; + +mod constants; diff --git a/third_party/rust/Inflector/src/string/pluralize/mod.rs b/third_party/rust/Inflector/src/string/pluralize/mod.rs new file mode 100644 index 0000000000..1caeea52e5 --- /dev/null +++ b/third_party/rust/Inflector/src/string/pluralize/mod.rs @@ -0,0 +1,194 @@ +#![deny(warnings)] +use regex::Regex; +use string::constants::UNACCONTABLE_WORDS; + +macro_rules! add_rule{ + ($r:ident, $rule:expr => $replace:expr) => { + $r.push((Regex::new($rule).unwrap(), $replace)); + } +} + +macro_rules! rules{ + ($r:ident; $($rule:expr => $replace:expr), *) => { + $( + add_rule!{$r, $rule => $replace} + )* + } +} + + +lazy_static!{ + static ref RULES: Vec<(Regex, &'static str)> = { + let mut r = Vec::with_capacity(24); + rules![r; + r"(\w*)s$" => "s", + r"(\w*([^aeiou]ese))$" => "", + r"(\w*(ax|test))is$" => "es", + r"(\w*(alias|[^aou]us|tlas|gas|ris))$" => "es", + r"(\w*(e[mn]u))s?$" => "s", + r"(\w*([^l]ias|[aeiou]las|[emjzr]as|[iu]am))$" => "", + r"(\w*(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat))(?:us|i)$" => "i", + r"(\w*(alumn|alg|vertebr))(?:a|ae)$" => "ae", + r"(\w*(seraph|cherub))(?:im)?$" => "im", + r"(\w*(her|at|gr))o$" => "oes", + r"(\w*(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor))(?:a|um)$" => "a", + r"(\w*(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat))(?:a|on)$" => "a", + r"(\w*)sis$" => "ses", + r"(\w*(kni|wi|li))fe$" => "ves", + r"(\w*(ar|l|ea|eo|oa|hoo))f$" => "ves", + r"(\w*([^aeiouy]|qu))y$" => "ies", + r"(\w*([^ch][ieo][ln]))ey$" => "ies", + r"(\w*(x|ch|ss|sh|zz)es)$" => "", + r"(\w*(x|ch|ss|sh|zz))$" => "es", + r"(\w*(matr|cod|mur|sil|vert|ind|append))(?:ix|ex)$" => "ices", + r"(\w*(m|l)(?:ice|ouse))$" => "ice", + r"(\w*(pe)(?:rson|ople))$" => "ople", + r"(\w*(child))(?:ren)?$" => "ren", + r"(\w*eaux)$" => "" + ]; + r + }; +} + +macro_rules! special_cases{ + ($s:ident, $($singular: expr => $plural:expr), *) => { + match &$s[..] { + $( + $singular => { + return $plural.to_owned(); + }, + )* + _ => () + } + } +} + + +/// Converts a `&str` to pluralized `String` +/// +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "foo_bars".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "ox"; +/// let expected_string: String = "oxen".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "crate"; +/// let expected_string: String = "crates".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "boxes"; +/// let expected_string: String = "boxes".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "vengeance"; +/// let expected_string: String = "vengeance".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "yoga"; +/// let expected_string: String = "yoga".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::pluralize::to_plural; +/// let mock_string: &str = "geometry"; +/// let expected_string: String = "geometries".to_owned(); +/// let asserted_string: String = to_plural(mock_string); +/// assert_eq!(asserted_string, expected_string); +/// +/// ``` +/// +pub fn to_plural(non_plural_string: &str) -> String { + if UNACCONTABLE_WORDS.contains(&non_plural_string.as_ref()) { + non_plural_string.to_owned() + } else { + special_cases![non_plural_string, + "ox" => "oxen", + "man" => "men", + "woman" => "women", + "die" => "dice", + "yes" => "yeses", + "foot" => "feet", + "eave" => "eaves", + "goose" => "geese", + "tooth" => "teeth", + "quiz" => "quizzes" + ]; + for &(ref rule, replace) in RULES.iter().rev() { + if let Some(c) = rule.captures(&non_plural_string) { + if let Some(c) = c.get(1) { + return format!("{}{}", c.as_str(), replace); + } + } + } + + format!("{}s", non_plural_string) + } +} + + +#[cfg(test)] +mod tests { + + macro_rules! as_item { + ($i:item) => { $i }; + } + + macro_rules! make_tests{ + ($($singular:ident => $plural:ident); *) =>{ + $( + as_item! { + #[test] + fn $singular(){ + assert_eq!( + stringify!($plural), + super::to_plural(stringify!($singular)) + ); + } + } + )* + } + } + + #[test] + fn boxes() { + assert_eq!("boxes", super::to_plural("box")); + } + + make_tests!{ + geometry => geometries; + ox => oxen; + woman => women; + test => tests; + axis => axes; + knife => knives; + agendum => agenda; + elf => elves; + zoology => zoology + } +} diff --git a/third_party/rust/Inflector/src/string/singularize/mod.rs b/third_party/rust/Inflector/src/string/singularize/mod.rs new file mode 100644 index 0000000000..60e0b51ca7 --- /dev/null +++ b/third_party/rust/Inflector/src/string/singularize/mod.rs @@ -0,0 +1,189 @@ +use regex::Regex; +use string::constants::UNACCONTABLE_WORDS; + +macro_rules! special_cases{ + ($s:ident, $($singular: expr => $plural:expr), *) => { + match &$s[..] { + $( + $singular => { + return $plural.to_owned(); + }, + )* + _ => () + } + } +} + + +/// Converts a `&str` to singularized `String` +/// +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "foo_bars"; +/// let expected_string: String = "foo_bar".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "oxen"; +/// let expected_string: String = "ox".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "crates"; +/// let expected_string: String = "crate".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "oxen"; +/// let expected_string: String = "ox".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "boxes"; +/// let expected_string: String = "box".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "vengeance"; +/// let expected_string: String = "vengeance".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::string::singularize::to_singular; +/// let mock_string: &str = "yoga"; +/// let expected_string: String = "yoga".to_owned(); +/// let asserted_string: String = to_singular(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// +pub fn to_singular(non_singular_string: &str) -> String { + if UNACCONTABLE_WORDS.contains(&non_singular_string.as_ref()) { + non_singular_string.to_owned() + } else { + special_cases![non_singular_string, + "oxen" => "ox", + "boxes" => "box", + "men" => "man", + "women" => "woman", + "dice" => "die", + "yeses" => "yes", + "feet" => "foot", + "eaves" => "eave", + "geese" => "goose", + "teeth" => "tooth", + "quizzes" => "quiz" + ]; + for &(ref rule, replace) in RULES.iter().rev() { + if let Some(captures) = rule.captures(&non_singular_string) { + if let Some(c) = captures.get(1) { + let mut buf = String::new(); + captures.expand(&format!("{}{}", c.as_str(), replace), &mut buf); + return buf; + } + } + } + + format!("{}", non_singular_string) + } +} + +macro_rules! add_rule{ + ($r:ident, $rule:expr => $replace:expr) => { + $r.push((Regex::new($rule).unwrap(), $replace)); + } +} + +macro_rules! rules{ + ($r:ident; $($rule:expr => $replace:expr), *) => { + $( + add_rule!{$r, $rule => $replace} + )* + } +} + + +lazy_static!{ + static ref RULES: Vec<(Regex, &'static str)> = { + let mut r = Vec::with_capacity(27); + rules![r; + r"(\w*)s$" => "", + r"(\w*)(ss)$" => "$2", + r"(n)ews$" => "ews", + r"(\w*)(o)es$" => "", + r"(\w*)([ti])a$" => "um", + r"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$" => "sis", + r"(^analy)(sis|ses)$" => "sis", + r"(\w*)([^f])ves$" => "fe", + r"(\w*)(hive)s$" => "", + r"(\w*)(tive)s$" => "", + r"(\w*)([lr])ves$" => "f", + r"(\w*([^aeiouy]|qu))ies$" => "y", + r"(s)eries$" => "eries", + r"(m)ovies$" => "ovie", + r"(\w*)(x|ch|ss|sh)es$" => "$2", + r"(m|l)ice$" => "ouse", + r"(bus)(es)?$" => "", + r"(shoe)s$" => "", + r"(cris|test)(is|es)$" => "is", + r"^(a)x[ie]s$" => "xis", + r"(octop|vir)(us|i)$" => "us", + r"(alias|status)(es)?$" => "", + r"^(ox)en" => "", + r"(vert|ind)ices$" => "ex", + r"(matr)ices$" => "ix", + r"(quiz)zes$" => "", + r"(database)s$" => "" + ]; + r + }; +} + +#[test] +fn singularize_ies_suffix() { + assert_eq!("reply", to_singular("replies")); + assert_eq!("lady", to_singular("ladies")); + assert_eq!("soliloquy", to_singular("soliloquies")); +} + +#[test] +fn singularize_ss_suffix() { + assert_eq!("glass", to_singular("glass")); + assert_eq!("access", to_singular("access")); + assert_eq!("glass", to_singular("glasses")); + assert_eq!("witch", to_singular("witches")); + assert_eq!("dish", to_singular("dishes")); +} + +#[test] +fn singularize_string_if_a_regex_will_match() { + let expected_string: String = "ox".to_owned(); + let asserted_string: String = to_singular("oxen"); + assert!(expected_string == asserted_string); + +} + +#[test] +fn singularize_string_returns_none_option_if_no_match() { + let expected_string: String = "bacon".to_owned(); + let asserted_string: String = to_singular("bacon"); + + assert!(expected_string == asserted_string); +} diff --git a/third_party/rust/Inflector/src/suffix/foreignkey/mod.rs b/third_party/rust/Inflector/src/suffix/foreignkey/mod.rs new file mode 100644 index 0000000000..e46696d4e7 --- /dev/null +++ b/third_party/rust/Inflector/src/suffix/foreignkey/mod.rs @@ -0,0 +1,139 @@ +use cases::snakecase::to_snake_case; + +/// Converts a `&str` to a `foreign_key` +/// +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "foo_bar"; +/// let expected_string: String = "foo_bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "Foo bar"; +/// let expected_string: String = "foo_bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "Foo Bar"; +/// let expected_string: String = "foo_bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "Foo::Bar"; +/// let expected_string: String = "bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "Test::Foo::Bar"; +/// let expected_string: String = "bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "FooBar"; +/// let expected_string: String = "foo_bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "fooBar"; +/// let expected_string: String = "foo_bar_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::to_foreign_key; +/// let mock_string: &str = "fooBar3"; +/// let expected_string: String = "foo_bar_3_id".to_owned(); +/// let asserted_string: String = to_foreign_key(mock_string); +/// assert!(asserted_string == expected_string); +/// +/// ``` +pub fn to_foreign_key(non_foreign_key_string: &str) -> String { + if non_foreign_key_string.contains("::") { + let split_string: Vec<&str> = non_foreign_key_string.split("::").collect(); + safe_convert(split_string[split_string.len() - 1]) + } else { + safe_convert(non_foreign_key_string) + } +} +fn safe_convert(safe_string: &str) -> String { + let snake_cased: String = to_snake_case(safe_string); + if snake_cased.ends_with("_id") { + snake_cased + } else { + format!("{}{}", snake_cased, "_id") + } +} + +/// Determines if a `&str` is a `foreign_key` +/// +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "Foo bar string that is really really long"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == false); +/// +/// ``` +/// ``` +/// use inflector::suffix::foreignkey::is_foreign_key; +/// let mock_string: &str = "foo_bar_string_that_is_really_really_long_id"; +/// let asserted_bool: bool = is_foreign_key(mock_string); +/// assert!(asserted_bool == true); +/// +/// ``` +pub fn is_foreign_key(test_string: &str) -> bool { + to_foreign_key(test_string.clone()) == test_string +} diff --git a/third_party/rust/Inflector/src/suffix/mod.rs b/third_party/rust/Inflector/src/suffix/mod.rs new file mode 100644 index 0000000000..2083cd5881 --- /dev/null +++ b/third_party/rust/Inflector/src/suffix/mod.rs @@ -0,0 +1,5 @@ +#![deny(warnings)] +/// Provides foreign key conversion for String. +/// +/// Example string `foo` becomes `foo_id` +pub mod foreignkey; |