Compare commits

...

40 Commits
v0.4.0 ... main

Author SHA1 Message Date
John Zacarias Jekel 0179a99a32 Optimizations and cleanup 1 year ago
John Zacarias Jekel 1dabce5224 An even further performance improvement: we are no longer attempting to support words without vowels 1 year ago
John Zacarias Jekel e48f584262 More performance improvements 1 year ago
John Jekel 4e28518ab3 More progress with new implementation 1 year ago
John Zacarias Jekel 3d4dbf1ae4 Continue improving the new rewrite's efficiency 1 year ago
John Zacarias Jekel 8e676b449d Begin a new rewrite that has more efficient loops 1 year ago
John Zacarias Jekel 1c1df67d64 Begin rewriting translation function to be more efficient 1 year ago
John Zacarias Jekel 10af4bd813 Increment minor version number, remove translate_strings.rs and other old code 1 year ago
John Zacarias Jekel ee2eef8b25 Add missing benches fro byte_string.rs 1 year ago
John Zacarias Jekel 21225aa4bc Finish docs for byte_string.rs 1 year ago
John Zacarias Jekel a97120228a Minor performance optimization 1 year ago
John Jekel 406484b45e Last doc progress before bed 1 year ago
John Jekel 22c7944a7d Work on docs for byte_string.rs 1 year ago
John Zacarias Jekel a7866e648c Begin working on docs for byte_string.rs 1 year ago
John Zacarias Jekel 796543722a Fix benches 1 year ago
John Jekel 80fa163ce4 Performance optimizations 1 year ago
John Jekel edcde04247 Add comments 1 year ago
John Jekel 1d83496e8a Use extend_from_slice which is more efficient 1 year ago
John Jekel c9663b9e14 Add a reminder for myself to not forget to add integration tests 1 year ago
John Jekel a425325fe6 Improve docs; also improve efficiency in string.rs 1 year ago
John Zacarias Jekel b9d341553b More progress 1 year ago
John Zacarias Jekel 47cbf3aba0 Move translate_word.rs to byte_string.rs 1 year ago
John Zacarias Jekel 92d817489d helpers.rs in now fully moved to byte_string.rs 1 year ago
John Zacarias Jekel c37d6a1b94 Move more things to byte_string.rs 1 year ago
John Zacarias Jekel 197fd51228 Even more cleanup 1 year ago
John Zacarias Jekel c046d15723 More restructuring 1 year ago
John Zacarias Jekel dc6bb6a0d0 Begin re-restructuring 1 year ago
John Zacarias Jekel d03c413ee7 More ASCII progress 1 year ago
John Zacarias Jekel 2d2333677c Begin restructuring/seperating ascii from utf8 1 year ago
John Zacarias Jekel 2be7ede4ee Seperate nightly-features into subfeatures 1 year ago
John Zacarias Jekel 97cc72fc47 Very minor performance benefit from generics 1 year ago
John Zacarias Jekel bc05413834 Add a generic UTF-8 regular translate function, and use it to power other functions when nightly-features is enabled 1 year ago
John Zacarias Jekel e535a69ac3 Add generic function for UTF-8 word translation 1 year ago
John Zacarias Jekel 4d9a89dec2 Add another helper function 1 year ago
John Zacarias Jekel 9ebeb071da Experiment with const generics 1 year ago
John Zacarias Jekel e232c34202 Minor improvements 1 year ago
John Zacarias Jekel 0684da4741 Now ascii functions use Vec<u8> internally and convert as needed for higher speed 1 year ago
John Zacarias Jekel efbcba6080 Begin transitioning ascii functions (at least internally) to Vec<u8> for greater speed 1 year ago
John Zacarias Jekel 39bdc0eb62 ASCII performance improvements 1 year ago
John Zacarias Jekel 1c0c52a975 Minor improvements 1 year ago
  1. 10
      Cargo.toml
  2. 36
      README.md
  3. 1
      TODO integration tests for ALL regular and byte_string functions.txt
  4. 48
      src/anslatortray.rs
  5. 1060
      src/byte_string.rs
  6. 109
      src/helpers.rs
  7. 23
      src/lib.rs
  8. 397
      src/string.rs
  9. 903
      src/translate_strings.rs
  10. 482
      src/translate_words.rs

@ -1,6 +1,6 @@
[package]
name = "anslatortray"
version = "0.4.0"
version = "0.5.0"
description = "A simple Rust library to translate from English to Pig Latin!"
authors = ["John Zacarias Jekel <john@jekel.ca>"]
readme = "README.md"
@ -16,7 +16,8 @@ documentation = "https://docs.rs/anslatortray/latest/anslatortray/"
[features]
default = []
nightly-features = []
nightly-features = ["nightly-features-benches"]
nightly-features-benches = []
[lib]
name = "anslatortray"
@ -26,11 +27,6 @@ path = "src/lib.rs"
name = "anslatortray"
path = "src/anslatortray.rs"
#[features]
#default = ["default_style_way"]
#default_style_way = []
#default_style_yay = []
[profile.dev]
incremental = true

@ -6,6 +6,21 @@ A simple Rust library to translate from English to Pig Latin!
Essentially, the word is reorganized in an effort to hide its true meaning, which can be lots of fun!
# A Quick Example
After adding Anslatortray as a dependency in your crate, try compiling this example code:
```rust
use anslatortray::translate;
fn main() {
//Prints "Ellohay orldway omfray ethay Anslatortray orfay Ustray!"
println!("{}", translate("Hello world from the Translator for Rust!"));
}
```
# Tell me more!
The Anslatortray library can help out by converting any English text into Pig Latin quickly and easily. It is **incredibly fast** (see the Performance section below) and **requires no dependencies**!
You can translate multiple sentences, including numbers, punctuation, and spacing, with a single call to `anslatortray::translate()`.
@ -17,27 +32,12 @@ Be sure to check out the documentation at <https://docs.rs/anslatortray/latest/a
# Building and Installation
If you wish to use the library in your crate, add anslatortray as a dependency and follow along with the example below, or <a href="https://docs.rs/anslatortray/latest/anslatortray/">check out the documentation</a> for more.
If you wish to use the library in your crate, add anslatortray as a dependency and <a href="https://docs.rs/anslatortray/latest/anslatortray/">check out the documentation</a>.
If you wish to use the `anslatortray` standalone binary, clone `https://git.jekel.ca/JZJ/anslatortray.git`, do `cargo build --release`, and you'll find the binary in the target/release directory.
If you wish to use the `anslatortray` standalone binary (shown in the next section), clone `https://git.jekel.ca/JZJ/anslatortray.git`, do `cargo build --release`, and you'll find the binary in the target/release directory.
See the <a href="https://git.jekel.ca/JZJ/anslatortray-rs/wiki/Building-And-Installing">wiki</a> for more information.
# A Quick Example
After adding Anslatortray as a dependency in your crate, try compiling this example code:
```rust
use anslatortray::translate;
fn main() {
//Prints "Ellohay orldway omfray ethay Anslatortray orfay Ustray!"
println!("{}", translate("Hello world from the Translator for Rust!"));
}
```
<a href="https://docs.rs/anslatortray/latest/anslatortray/">Check out the documentation</a> for more examples!
# anslatortray CLI Tool Usage
There are several options supported by the `anslatortray` command:
@ -102,7 +102,7 @@ See <a href="https://git.jekel.ca/JZJ/anslatortray-rs/wiki/Using-the-anslatortra
Check out the <a href="https://git.jekel.ca/JZJ/anslatortray-rs/wiki/Performance">wiki page about Anslatortray's performance</a>!
Spoiler: It can translate one word in under **129ns** on average in the default UTF-8 mode, and in under **94ns** on average in ASCII-only mode on my dated system :)
Spoiler: `anslatortray::translate()` can process one word in under **50ns** on average!
# Useful Links

@ -9,27 +9,7 @@
/* Imports */
use anslatortray::translate;
use anslatortray::translate_ascii;
/* Constants */
//TODO
/* Macros */
//TODO (also pub(crate) use the_macro statements here too)
/* Static Variables */
//TODO
/* Types */
//TODO
/* Associated Functions and Methods */
//TODO
use anslatortray::byte_string;
/* Functions */
@ -71,7 +51,7 @@ fn help() {
eprintln!("--translate-args Translates all remaining arguments provided and outputs them to stdout");
eprintln!("--stdin-to-stdout Translates input from stdin directly to stdout");
eprintln!("\n{}", translate_ascii("Have a good day!"));
eprintln!("\n{}", translate("Have a good day!"));
}
fn interactive(args: &Vec<String>) {
@ -104,6 +84,7 @@ fn file(args: &Vec<String>) {
}
//TODO error handling
//TODO switch to using byte_string for efficiency
let input_file = &args[0];
let output_file = &args[1];
@ -133,35 +114,30 @@ fn benchmark_file(args: &Vec<String>) {
let file_contents = std::fs::read_to_string(input_file).unwrap();
let mut total_duration_utf8 = std::time::Duration::new(0, 0);
let mut total_duration_regular = std::time::Duration::new(0, 0);
for _ in 0..iterations {
let start_time = std::time::Instant::now();
let translated_file_contents = translate(&file_contents);
let time_to_translate = start_time.elapsed();
total_duration_utf8 += time_to_translate;
total_duration_regular += time_to_translate;
std::fs::write("/dev/null", &translated_file_contents).unwrap();//TODO avoid needing unix
}
eprintln!("Sucessful: UTF-8 translation took {}ns to translate on average over {} runs.", total_duration_utf8.as_nanos() / iterations, iterations);
for character in file_contents.chars() {
if !character.is_ascii() {
eprintln!("Not performing ASCII translation benchmarks as the file's contents are not entirely ASCII.");
return;
}
}
eprintln!("Sucessful: Regular translation took {}ns to translate on average over {} runs.", total_duration_regular.as_nanos() / iterations, iterations);
let mut total_duration_ascii = std::time::Duration::new(0, 0);
let mut total_duration_byte_string = std::time::Duration::new(0, 0);
let mut translated_file_contents = Vec::<u8>::new();//TODO set a sane initial size
for _ in 0..iterations {
let start_time = std::time::Instant::now();
let translated_file_contents = translate_ascii(&file_contents);
translated_file_contents.truncate(0);
byte_string::translate(file_contents.as_bytes(), &mut translated_file_contents);
let time_to_translate = start_time.elapsed();
total_duration_ascii += time_to_translate;
total_duration_byte_string += time_to_translate;
std::fs::write("/dev/null", &translated_file_contents).unwrap();//TODO avoid needing unix
}
eprintln!("Sucessful: ASCII translation took {}ns to translate on average over {} runs.", total_duration_ascii.as_nanos() / iterations, iterations);
eprintln!("Sucessful: Byte-string translation with reused allocations took {}ns to translate on average over {} runs.", total_duration_byte_string.as_nanos() / iterations, iterations);
}
fn translate_args(args: &Vec<String>) {

File diff suppressed because it is too large Load Diff

@ -1,109 +0,0 @@
/* helpers.rs
* Copyright (C) 2022 John Jekel
* See the LICENSE file at the root of the project for licensing info.
*
* Contains helper functions
*
*/
/* Functions */
//Returns whether a letter is a vowel or not.
pub(crate) fn is_vowel(letter: char) -> bool {
match letter.to_ascii_lowercase() {
'a' | 'e' | 'i' | 'o' | 'u' => { return true; }
_ => { return false; }
}
}
//Returns whether a letter is y or not.
pub(crate) fn is_y(letter: char) -> bool {
return letter.to_ascii_lowercase() == 'y';
}
//Returns whether an entire word is upper case or not
pub(crate) fn word_is_uppercase(english_word: &str) -> bool {
//We can't get the last character without iterating through the whole string since this is UTF-8
//So the best we can do is exit out early if we encounter a lower-case character (we can't use the huristic in word_is_uppercase_ascii)
for letter in english_word.chars() {
if letter.is_ascii_lowercase() {
return false;
}
}
return true;
}
//Returns whether an entire word is upper case or not (the word must only contain ASCII characters)
pub(crate) fn word_is_uppercase_ascii(english_word: &str) -> bool {
//Asume length is non-zero
//Heuristic: If the last letter of the word is uppercase, likely the whole word is uppercase
return (english_word.as_bytes()[english_word.as_bytes().len() - 1] as char).is_ascii_uppercase();
}
/* Tests */
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_vowel() {
for letter in "aeiouAEIOU".chars() {
assert!(is_vowel(letter));
}
for letter in "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ".chars() {
assert!(!is_vowel(letter));
}
for not_letter in " !@#$%^&*()_+={}|\":>?~`\\][';/.,\t\n".chars() {
assert!(!is_vowel(not_letter));
}
}
#[test]
fn test_is_y() {
for letter in "yY".chars() {
assert!(is_y(letter));
}
for letter in "abcdefghijklmnopqrstuvwxzABCDEFGHIJKLMNOPQRSTUVWXZ".chars() {
assert!(!is_y(letter));
}
for not_letter in " !@#$%^&*()_+={}|\":>?~`\\][';/.,\t\n".chars() {
assert!(!is_y(not_letter));
}
}
#[test]
fn test_word_is_uppercase() {
assert!(word_is_uppercase("HELLO"));
assert!(word_is_uppercase("WORLD"));
assert!(word_is_uppercase("I"));
assert!(!word_is_uppercase("would"));
assert!(!word_is_uppercase("like"));
assert!(!word_is_uppercase("a"));
assert!(!word_is_uppercase("pizza"));
assert!(!word_is_uppercase("Sussus"));
assert!(!word_is_uppercase("Amogus"));
}
#[test]
fn test_word_is_uppercase_ascii() {
assert!(word_is_uppercase_ascii("HELLO"));
assert!(word_is_uppercase_ascii("WORLD"));
assert!(word_is_uppercase_ascii("I"));
assert!(!word_is_uppercase_ascii("would"));
assert!(!word_is_uppercase_ascii("like"));
assert!(!word_is_uppercase_ascii("a"));
assert!(!word_is_uppercase_ascii("pizza"));
assert!(!word_is_uppercase_ascii("Sussus"));
assert!(!word_is_uppercase_ascii("Amogus"));
}
}

@ -1,16 +1,7 @@
//!Anslatortray for Rust
//!Anslatortray for Rust: A simple Rust library to translate from English to Pig Latin.
//!
//!Welcome to the Anslatortray Documentation!
//!
//!A simple Rust library to translate from English to Pig Latin.
//!
//!The Anslatortray library can help out by converting any English text into Pig Latin quickly and easily. It is **incredibly fast** and **requires no dependencies**!
//!
//!You can translate multiple sentences, including numbers, punctuation, and spacing, with a single call to [`translate()`].
//!The function handles edge cases quite well (words without vowels, one-letter words, contractions, ALL CAPS, etc.), though there is always room for improvement.
//!
//!If you have suggestions for how the project could be improved, please visit the repository's issues page on <a href="https://github.com/JZJisawesome/anslatortray-rs/issues">Github</a> or <a href="https://gitlab.com/JZJisawesome/anslatortray-rs/-/issues">GitLab</a> or contact me directly :)
//!
//!# Building and Installation
//!
//!If you wish to use the library in your crate, add anslatortray as a dependency and follow along with the examples below, or check out the rest of the documentation.
@ -48,7 +39,7 @@
//!
//!If none of these suit your needs, you can also choose your own suffixes with [`translate_with_style()`]
//!
//!If you want more speed, and you know your text contains only ASCII characters, check out [`translate_ascii()`]
//!If you want even more speed than the regular translation functions bring to the table, check out the [`byte_string`] module.
//!
//!# Useful Links
//!<a href="https://git.jekel.ca/JZJ/anslatortray-rs">Click here to visit the Anslatortray for Rust Git Repository!</a>.
@ -72,13 +63,11 @@
/* Nightly Features */
//Only enabled if the relevant Cargo feature is
#![cfg_attr(feature = "nightly-features", feature(test))]
#![cfg_attr(feature = "nightly-features-benches", feature(test))]
/* Imports */
mod helpers;
mod translate_strings;
mod translate_words;
pub mod byte_string;
mod string;
pub use translate_strings::{translate, translate_way, translate_yay, translate_hay, translate_ferb, translate_with_style};
pub use translate_strings::{translate_ascii, translate_way_ascii, translate_yay_ascii, translate_hay_ascii, translate_ferb_ascii, translate_with_style_ascii};
pub use string::{translate, translate_way, translate_yay, translate_hay, translate_ferb, translate_with_style};

@ -0,0 +1,397 @@
/* string.rs
* By: John Jekel
* Copyright (C) 2022 John Jekel
* See the LICENSE file at the root of the project for licensing info.
*
* Translation functions operating on &str and String (the ones most users will want to use)
*
*/
/* Imports */
use crate::byte_string::translate_with_style_lower_and_upper_suffixes as translate_byte_string_with_style_lower_and_upper_suffixes;
/* Functions */
///Translates a multi-word string (including punctuation) into Pig Latin!
///
///Uses the default suffix and special_case_suffix, "ay" and "way" respectively when calling [`translate_with_style()`].
///
///Equivalent to [`translate_way()`].
///
///# Examples
///
///```
///use anslatortray::translate;
///
///assert_eq!(translate("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyway Englishway exttay. Itway ancay evenway andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeway asescay. Atthay isway away ontractioncay, asway ellway asway away ordway erewhay ethay onlyway owelvay isway yway. Eatnay, allway atthay orksway!"
///);
///
///assert_eq!(translate("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifway away ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areway-ifficultday-arenway't-eythay?");
///```
pub fn translate(english: &str) -> String {
return translate_way(english);
}
///Translates a multi-word string (including punctuation) into Pig Latin (way-style)!
///
///Uses the suffix and special_case_suffix "ay" and "way" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_way;
///
///assert_eq!(translate_way("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_way("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyway Englishway exttay. Itway ancay evenway andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_way("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeway asescay. Atthay isway away ontractioncay, asway ellway asway away ordway erewhay ethay onlyway owelvay isway yway. Eatnay, allway atthay orksway!"
///);
///
///assert_eq!(translate_way("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifway away ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_way("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_way("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_way("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areway-ifficultday-arenway't-eythay?");
///```
pub fn translate_way(english: &str) -> String {
return translate_with_style_lower_and_upper_suffixes(english, "ay", "way", "AY", "WAY");
}
///Translates a multi-word string (including punctuation) into Pig Latin (yay-style)!
///
///Uses the suffix and special_case_suffix "ay" and "yay" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_yay;
///
///assert_eq!(translate_yay("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_yay("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyyay Englishyay exttay. Ityay ancay evenyay andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_yay("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeyay asescay. Atthay isyay ayay ontractioncay, asyay ellway asyay ayay ordway erewhay ethay onlyyay owelvay isyay yyay. Eatnay, allyay atthay orksway!"
///);
///
///assert_eq!(translate_yay("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifyay ayay ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_yay("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_yay("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_yay("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areyay-ifficultday-arenyay't-eythay?");
///```
pub fn translate_yay(english: &str) -> String {
return translate_with_style_lower_and_upper_suffixes(english, "ay", "yay", "AY", "YAY");
}
///Translates a multi-word string (including punctuation) into Pig Latin (hay-style)!
///
///Uses the suffix and special_case_suffix "ay" and "hay" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_hay;
///
///assert_eq!(translate_hay("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_hay("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyhay Englishhay exttay. Ithay ancay evenhay andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_hay("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgehay asescay. Atthay ishay ahay ontractioncay, ashay ellway ashay ahay ordway erewhay ethay onlyhay owelvay ishay yhay. Eatnay, allhay atthay orksway!"
///);
///
///assert_eq!(translate_hay("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifhay ahay ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_hay("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_hay("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_hay("Hyphens-are-difficult-aren't-they?"), "Yphenshay-arehay-ifficultday-arenhay't-eythay?");
///```
pub fn translate_hay(english: &str) -> String {
return translate_with_style_lower_and_upper_suffixes(english, "ay", "hay", "AY", "HAY");
}
///Translates a multi-word string (including punctuation) into Ferb Latin!
///
///Uses the suffix and special_case_suffix "erb" and "ferb" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_ferb;
///
///assert_eq!(translate_ferb("Hello world from the coolest Ferb Latin translator!"), "Elloherb orldwerb omfrerb etherb oolestcerb Erbferb Atinlerb anslatortrerb!");
///
///assert_eq!(translate_ferb("This library can translate any English text. It can even handle multiple sentences!"),
/// "Istherb ibrarylerb ancerb anslatetrerb anyferb Englishferb extterb. Itferb ancerb evenferb andleherb ultiplemerb entencesserb!"
///);
///
///assert_eq!(translate_ferb("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlerb's ytrerb omeserb edgeferb asescerb. Attherb isferb aferb ontractioncerb, asferb ellwerb asferb aferb ordwerb erewherb etherb onlyferb owelverb isferb yferb. Eatnerb, allferb attherb orkswerb!"
///);
///assert_eq!(translate_ferb("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwherb ifferb aferb ordwerb asherb onerb owelsverb, ikelerb istherb: bcdfghjklmnpqrstvwxzerb"
///);
///assert_eq!(translate_ferb("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcerb, oserb etherb euristicsherb akemerb ettyprerb oodgerb uessesgerb ithwerb atwherb eytherb're edferb!"
///);
///
///assert_eq!(translate_ferb("Hello-world"), "Elloherb-orldwerb");
///assert_eq!(translate_ferb("Hyphens-are-difficult-aren't-they?"), "Yphensherb-areferb-ifficultderb-arenferb't-eytherb?");
///```
pub fn translate_ferb(english: &str) -> String {
return translate_with_style_lower_and_upper_suffixes(english, "erb", "ferb", "ERB", "FERB");
}
///Translates a multi-word string (including punctuation) into a custom-styled play language!
///
///Pass the string you wish to translate, the suffix you wish to have appended to most words, and the suffix
///you wish to have appended in various special-cases (such as when a word is only one letter or starts with a vowel).
///
///Note: The suffixes must be entirely lower-case or weird results may occur.
///
///# Examples
///
///```
///use anslatortray::translate_with_style;
///
///let suffix = "ancy";
///let special_case_suffix = "fancy";
///
///assert_eq!(translate_with_style("Hello world from the coolest Pig Latin translator!", suffix, special_case_suffix),
/// "Ellohancy orldwancy omfrancy ethancy oolestcancy Igpancy Atinlancy anslatortrancy!"
///);
///
///assert_eq!(translate_with_style("This library can translate any English text. It can even handle multiple sentences!", suffix, special_case_suffix),
/// "Isthancy ibrarylancy ancancy anslatetrancy anyfancy Englishfancy exttancy. Itfancy ancancy evenfancy andlehancy ultiplemancy entencessancy!"
///);
///
///assert_eq!(translate_with_style("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!", suffix, special_case_suffix),
/// "Etlancy's ytrancy omesancy edgefancy asescancy. Atthancy isfancy afancy ontractioncancy, asfancy ellwancy asfancy afancy ordwancy erewhancy ethancy onlyfancy owelvancy isfancy yfancy. Eatnancy, allfancy atthancy orkswancy!"
///);
///
///assert_eq!(translate_with_style("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz", suffix, special_case_suffix),
/// "Atwhancy iffancy afancy ordwancy ashancy onancy owelsvancy, ikelancy isthancy: bcdfghjklmnpqrstvwxzancy"
///);
///
///assert_eq!(translate_with_style("Cool, so the heuristics make pretty good guesses with what they're fed!", suffix, special_case_suffix),
/// "Oolcancy, osancy ethancy euristicshancy akemancy ettyprancy oodgancy uessesgancy ithwancy atwhancy eythancy're edfancy!"
///);
///
///assert_eq!(translate_with_style("Hello-world", suffix, special_case_suffix), "Ellohancy-orldwancy");
///
///assert_eq!(translate_with_style("Hyphens-are-difficult-aren't-they?", suffix, special_case_suffix), "Yphenshancy-arefancy-ifficultdancy-arenfancy't-eythancy?");
///```
pub fn translate_with_style(english: &str, suffix_lower: &str, special_case_suffix_lower: &str) -> String {
//Convert the suffix and special_case_suffix we were provided to uppercase for words that are capitalized
let mut suffix_upper = String::with_capacity(suffix_lower.len());
for letter in suffix_lower.chars() {
suffix_upper.push(letter.to_ascii_uppercase());
}
let mut special_case_suffix_upper = String::with_capacity(special_case_suffix_lower.len());
for letter in special_case_suffix_lower.chars() {
special_case_suffix_upper.push(letter.to_ascii_uppercase());
}
return translate_with_style_lower_and_upper_suffixes (
english,
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper
);
}
//More efficient: Does not need to convert to upppercase at runtime
fn translate_with_style_lower_and_upper_suffixes (
english: &str,
suffix_lower: &str, special_case_suffix_lower: &str, suffix_upper: &str, special_case_suffix_upper: &str
) -> String {
//Convert the string slices to byte slices and translate those (only ASCII letters are affected, non-letters or UTF-8 are preserved)
let mut pig_latin_string_bytes = Vec::<u8>::with_capacity(english.len() * 2);//Plenty of headroom in case the words are very small or the suffixes are long
translate_byte_string_with_style_lower_and_upper_suffixes (
english.as_bytes(),
suffix_lower.as_bytes(), special_case_suffix_lower.as_bytes(), suffix_upper.as_bytes(), special_case_suffix_upper.as_bytes(),
&mut pig_latin_string_bytes
);
//This is safe since translate_byte_string_with_style does not touch any unicode bytes (it just copies them)
return unsafe { String::from_utf8_unchecked(pig_latin_string_bytes) };
}
/* Tests */
#[cfg(test)]
mod tests {
use super::*;
const SUFFIX_SPECIAL_CASE_SUFFIX_PAIRS: [(&str, &str); 9] = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
const SUFFIX_SPECIAL_CASE_SUFFIX_LOWER_UPPER_TUPLES: [(&str, &str, &str, &str); 9] = [
("ay", "way", "AY", "WAY"), ("ay", "yay", "AY", "YAY"), ("ay", "hay", "AY", "HAY"), ("erb", "ferb", "ERB", "FERB"),
("ancy", "fancy", "ANCY", "FANCY"), ("orange", "porange", "ORANGE", "PORANGE"),
("anana", "banana", "ANANA", "BANANA"), ("atin", "latin", "ATIN", "LATIN"), ("ust", "rust", "UST", "RUST"),
];
#[test]
fn test_translate_with_style() {
for pair in SUFFIX_SPECIAL_CASE_SUFFIX_PAIRS {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_with_style("Hello world from the coolest Pig Latin translator!", suffix, special_case_suffix),
"Elloh".to_string() + suffix + " orldw" + suffix + " omfr" + suffix + " eth" + suffix + " oolestc" + suffix + " Igp" + suffix + " Atinl" + suffix + " anslatortr" + suffix + "!"
);
assert_eq!(translate_with_style("This library can translate any English text. It can even handle multiple sentences!", suffix, special_case_suffix),
"Isth".to_string() + suffix + " ibraryl" + suffix + " anc" + suffix + " anslatetr" + suffix + " any" + special_case_suffix + " English" + special_case_suffix + " extt" + suffix +
". It" + special_case_suffix + " anc" + suffix + " even" + special_case_suffix + " andleh" + suffix + " ultiplem" + suffix + " entencess" + suffix + "!"
);
}
}
#[test]
fn test_translate_with_style_edgecases() {
for pair in SUFFIX_SPECIAL_CASE_SUFFIX_PAIRS {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_with_style("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!", suffix, special_case_suffix),
"Etl".to_string() + suffix + "'s ytr" + suffix + " omes" + suffix + " edge" + special_case_suffix + " asesc" + suffix + ". Atth" + suffix + " is" + special_case_suffix + " a" +
special_case_suffix + " ontractionc" + suffix + ", as" + special_case_suffix + " ellw" + suffix + " as" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix +
" erewh" + suffix + " eth" + suffix + " only" + special_case_suffix + " owelv" + suffix + " is" + special_case_suffix + " y" + special_case_suffix + ". Eatn" + suffix + ", all" +
special_case_suffix + " atth" + suffix + " orksw" + suffix + "!"
);
assert_eq!(translate_with_style("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz", suffix, special_case_suffix),
"Atwh".to_string() + suffix + " if" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix + " ash" + suffix + " on" + suffix + " owelsv" + suffix + ", ikel" + suffix + " isth" + suffix + ": bcdfghjklmnpqrstvwxz" + suffix
);
assert_eq!(translate_with_style("Cool, so the heuristics make pretty good guesses with what they're fed!", suffix, special_case_suffix),
"Oolc".to_string() + suffix + ", os" + suffix + " eth" + suffix + " euristicsh" + suffix + " akem" + suffix + " ettypr" + suffix + " oodg" + suffix + " uessesg" + suffix + " ithw" + suffix + " atwh" + suffix + " eyth" + suffix + "'re edf" + suffix + "!"
);
assert_eq!(translate_with_style("Hello-world", suffix, special_case_suffix), "Elloh".to_string() + suffix + "-orldw" + suffix);
assert_eq!(translate_with_style("Hyphens-are-difficult-aren't-they?", suffix, special_case_suffix),
"Yphensh".to_string() + suffix + "-are" + special_case_suffix + "-ifficultd" + suffix + "-aren" + special_case_suffix + "'t-eyth" + suffix + "?"
);
}
}
#[test]
fn test_translate_with_style_uppercase() {
for pair in SUFFIX_SPECIAL_CASE_SUFFIX_LOWER_UPPER_TUPLES {
let suffix_lower = pair.0;
let special_case_suffix_lower = pair.1;
let suffix_upper = pair.2;
let special_case_suffix_upper = pair.3;
assert_eq!(translate_with_style("HELLO WORLD!", suffix_lower, special_case_suffix_lower),
"ELLOH".to_string() + suffix_upper + " ORLDW" + suffix_upper + "!"
);
assert_eq!(translate_with_style("ISN't THIS COOL?", suffix_lower, special_case_suffix_lower),
"ISN".to_string() + special_case_suffix_upper + "'t ISTH" + suffix_upper + " OOLC" + suffix_upper + "?"
);
assert_eq!(translate_with_style("What ABOUT a MIX?", suffix_lower, special_case_suffix_lower),
"Atwh".to_string() + suffix_lower + " ABOUT" + special_case_suffix_upper + " a" + special_case_suffix_lower + " IXM" + suffix_upper + "?"
);
assert_eq!(translate_with_style("Luke, I am your father!", suffix_lower, special_case_suffix_lower),//We don't want to capitalize single-letter words
"Ukel".to_string() + suffix_lower + ", I" + special_case_suffix_lower+ " am" + special_case_suffix_lower + " oury" + suffix_lower + " atherf" + suffix_lower + "!"
);
}
}
}
/* Benches */
#[cfg_attr(feature = "nightly-features-benches", cfg(test))]
#[cfg(feature = "nightly-features-benches")]
mod benches {
extern crate test;
use test::Bencher;
use super::*;
const PROJECT_DESCRIPTION: &str = "A simple Rust library to translate from English to Pig Latin!";
const LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
#[bench]
fn way_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate(PROJECT_DESCRIPTION); });
}
#[bench]
fn yay_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_yay(PROJECT_DESCRIPTION); });
}
#[bench]
fn hay_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_hay(PROJECT_DESCRIPTION); });
}
#[bench]
fn ferb_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_ferb(PROJECT_DESCRIPTION); });
}
#[bench]
fn way_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate(LOREM_IPSUM); });
}
#[bench]
fn yay_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_yay(LOREM_IPSUM); });
}
#[bench]
fn hay_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_hay(LOREM_IPSUM); });
}
#[bench]
fn ferb_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_ferb(LOREM_IPSUM); });
}
}

@ -1,903 +0,0 @@
/* translate_strings.rs
* Copyright (C) 2022 John Jekel
* See the LICENSE file at the root of the project for licensing info.
*
* Contains functions for translating multiple sentences.
*
*/
/* Imports */
use crate::translate_words::translate_word_with_style_reuse_buffers;
use crate::translate_words::translate_word_with_style_reuse_buffers_ascii;
/* Functions */
///Translates a multi-word string (including punctuation) into Pig Latin!
///
///Uses the default suffix and special_case_suffix, "ay" and "way" respectively when calling [`translate_with_style()`].
///
///Equivalent to [`translate_way()`].
///
///# Examples
///
///```
///use anslatortray::translate;
///
///assert_eq!(translate("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyway Englishway exttay. Itway ancay evenway andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeway asescay. Atthay isway away ontractioncay, asway ellway asway away ordway erewhay ethay onlyway owelvay isway yway. Eatnay, allway atthay orksway!"
///);
///
///assert_eq!(translate("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifway away ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areway-ifficultday-arenway't-eythay?");
///```
pub fn translate(english: &str) -> String {
return translate_way(english);
}
///Translates a multi-word string (including punctuation) into Pig Latin (Faster, but ASCII-only)!
///
///Faster than [`translate()`], but requires that the string only contains ASCII characters or else it may panic.
///
///Uses the default suffix and special_case_suffix, "ay" and "way" respectively when calling [`translate_with_style_ascii()`].
///
///Equivalent to [`translate_way_ascii()`].
///
///# Examples
///
///```
///use anslatortray::translate_ascii;
///
///assert_eq!(translate_ascii("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_ascii("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyway Englishway exttay. Itway ancay evenway andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeway asescay. Atthay isway away ontractioncay, asway ellway asway away ordway erewhay ethay onlyway owelvay isway yway. Eatnay, allway atthay orksway!"
///);
///
///assert_eq!(translate_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifway away ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_ascii("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_ascii("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areway-ifficultday-arenway't-eythay?");
///```
pub fn translate_ascii(english: &str) -> String {
return translate_way_ascii(english);
}
///Translates a multi-word string (including punctuation) into Pig Latin (way-style)!
///
///Uses the suffix and special_case_suffix "ay" and "way" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_way;
///
///assert_eq!(translate_way("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_way("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyway Englishway exttay. Itway ancay evenway andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_way("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeway asescay. Atthay isway away ontractioncay, asway ellway asway away ordway erewhay ethay onlyway owelvay isway yway. Eatnay, allway atthay orksway!"
///);
///
///assert_eq!(translate_way("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifway away ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_way("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_way("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_way("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areway-ifficultday-arenway't-eythay?");
///```
pub fn translate_way(english: &str) -> String {
return translate_with_style(english, "ay", "way");
}
///Translates a multi-word string (including punctuation) into Pig Latin (way-style) (Faster, but ASCII-only)!
///
///Faster than [`translate_way()`], but requires that the string only contains ASCII characters or else it may panic.
///
///Uses the suffix and special_case_suffix "ay" and "way" respectively when calling [`translate_with_style_ascii()`].
///
///# Examples
///
///```
///use anslatortray::translate_way_ascii;
///
///assert_eq!(translate_way_ascii("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_way_ascii("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyway Englishway exttay. Itway ancay evenway andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_way_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeway asescay. Atthay isway away ontractioncay, asway ellway asway away ordway erewhay ethay onlyway owelvay isway yway. Eatnay, allway atthay orksway!"
///);
///
///assert_eq!(translate_way_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifway away ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_way_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_way_ascii("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_way_ascii("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areway-ifficultday-arenway't-eythay?");
///```
pub fn translate_way_ascii(english: &str) -> String {
return translate_with_style_ascii(english, "ay", "way");
}
///Translates a multi-word string (including punctuation) into Pig Latin (yay-style)!
///
///Uses the suffix and special_case_suffix "ay" and "yay" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_yay;
///
///assert_eq!(translate_yay("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_yay("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyyay Englishyay exttay. Ityay ancay evenyay andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_yay("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeyay asescay. Atthay isyay ayay ontractioncay, asyay ellway asyay ayay ordway erewhay ethay onlyyay owelvay isyay yyay. Eatnay, allyay atthay orksway!"
///);
///
///assert_eq!(translate_yay("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifyay ayay ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_yay("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_yay("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_yay("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areyay-ifficultday-arenyay't-eythay?");
///```
pub fn translate_yay(english: &str) -> String {
return translate_with_style(english, "ay", "yay");
}
///Translates a multi-word string (including punctuation) into Pig Latin (yay-style) (Faster, but ASCII-only)!
///
///Faster than [`translate_yay()`], but requires that the string only contains ASCII characters or else it may panic.
///
///Uses the suffix and special_case_suffix "ay" and "yay" respectively when calling [`translate_with_style_ascii()`].
///
///# Examples
///
///```
///use anslatortray::translate_yay_ascii;
///
///assert_eq!(translate_yay_ascii("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_yay_ascii("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyyay Englishyay exttay. Ityay ancay evenyay andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_yay_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgeyay asescay. Atthay isyay ayay ontractioncay, asyay ellway asyay ayay ordway erewhay ethay onlyyay owelvay isyay yyay. Eatnay, allyay atthay orksway!"
///);
///
///assert_eq!(translate_yay_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifyay ayay ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_yay_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_yay_ascii("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_yay_ascii("Hyphens-are-difficult-aren't-they?"), "Yphenshay-areyay-ifficultday-arenyay't-eythay?");
///```
pub fn translate_yay_ascii(english: &str) -> String {
return translate_with_style_ascii(english, "ay", "yay");
}
///Translates a multi-word string (including punctuation) into Pig Latin (hay-style)!
///
///Uses the suffix and special_case_suffix "ay" and "hay" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_hay;
///
///assert_eq!(translate_hay("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_hay("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyhay Englishhay exttay. Ithay ancay evenhay andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_hay("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgehay asescay. Atthay ishay ahay ontractioncay, ashay ellway ashay ahay ordway erewhay ethay onlyhay owelvay ishay yhay. Eatnay, allhay atthay orksway!"
///);
///
///assert_eq!(translate_hay("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifhay ahay ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_hay("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_hay("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_hay("Hyphens-are-difficult-aren't-they?"), "Yphenshay-arehay-ifficultday-arenhay't-eythay?");
///```
pub fn translate_hay(english: &str) -> String {
return translate_with_style(english, "ay", "hay");
}
///Translates a multi-word string (including punctuation) into Pig Latin (hay-style) (Faster, but ASCII-only)!
///
///Faster than [`translate_hay()`], but requires that the string only contains ASCII characters or else it may panic.
///
///Uses the suffix and special_case_suffix "ay" and "hay" respectively when calling [`translate_with_style_ascii()`].
///
///# Examples
///
///```
///use anslatortray::translate_hay_ascii;
///
///assert_eq!(translate_hay_ascii("Hello world from the coolest Pig Latin translator!"), "Ellohay orldway omfray ethay oolestcay Igpay Atinlay anslatortray!");
///
///assert_eq!(translate_hay_ascii("This library can translate any English text. It can even handle multiple sentences!"),
/// "Isthay ibrarylay ancay anslatetray anyhay Englishhay exttay. Ithay ancay evenhay andlehay ultiplemay entencessay!"
///);
///
///assert_eq!(translate_hay_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlay's ytray omesay edgehay asescay. Atthay ishay ahay ontractioncay, ashay ellway ashay ahay ordway erewhay ethay onlyhay owelvay ishay yhay. Eatnay, allhay atthay orksway!"
///);
///
///assert_eq!(translate_hay_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwhay ifhay ahay ordway ashay onay owelsvay, ikelay isthay: bcdfghjklmnpqrstvwxzay"
///);
///
///assert_eq!(translate_hay_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcay, osay ethay euristicshay akemay ettypray oodgay uessesgay ithway atwhay eythay're edfay!"
///);
///
///assert_eq!(translate_hay_ascii("Hello-world"), "Ellohay-orldway");
///assert_eq!(translate_hay_ascii("Hyphens-are-difficult-aren't-they?"), "Yphenshay-arehay-ifficultday-arenhay't-eythay?");
///```
pub fn translate_hay_ascii(english: &str) -> String {
return translate_with_style_ascii(english, "ay", "hay");
}
///Translates a multi-word string (including punctuation) into Ferb Latin!
///
///Uses the suffix and special_case_suffix "erb" and "ferb" respectively when calling [`translate_with_style()`].
///
///# Examples
///
///```
///use anslatortray::translate_ferb;
///
///assert_eq!(translate_ferb("Hello world from the coolest Ferb Latin translator!"), "Elloherb orldwerb omfrerb etherb oolestcerb Erbferb Atinlerb anslatortrerb!");
///
///assert_eq!(translate_ferb("This library can translate any English text. It can even handle multiple sentences!"),
/// "Istherb ibrarylerb ancerb anslatetrerb anyferb Englishferb extterb. Itferb ancerb evenferb andleherb ultiplemerb entencesserb!"
///);
///
///assert_eq!(translate_ferb("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlerb's ytrerb omeserb edgeferb asescerb. Attherb isferb aferb ontractioncerb, asferb ellwerb asferb aferb ordwerb erewherb etherb onlyferb owelverb isferb yferb. Eatnerb, allferb attherb orkswerb!"
///);
///assert_eq!(translate_ferb("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwherb ifferb aferb ordwerb asherb onerb owelsverb, ikelerb istherb: bcdfghjklmnpqrstvwxzerb"
///);
///assert_eq!(translate_ferb("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcerb, oserb etherb euristicsherb akemerb ettyprerb oodgerb uessesgerb ithwerb atwherb eytherb're edferb!"
///);
///
///assert_eq!(translate_ferb("Hello-world"), "Elloherb-orldwerb");
///assert_eq!(translate_ferb("Hyphens-are-difficult-aren't-they?"), "Yphensherb-areferb-ifficultderb-arenferb't-eytherb?");
///```
pub fn translate_ferb(english: &str) -> String {
return translate_with_style(english, "erb", "ferb");
}
///Translates a multi-word string (including punctuation) into Ferb Latin (Faster, but ASCII-only)!
///
///Faster than [`translate_hay()`], but requires that the string only contains ASCII characters or else it may panic.
///
///Uses the suffix and special_case_suffix "erb" and "ferb" respectively when calling [`translate_with_style_ascii()`].
///
///# Examples
///
///```
///use anslatortray::translate_ferb_ascii;
///
///assert_eq!(translate_ferb_ascii("Hello world from the coolest Ferb Latin translator!"), "Elloherb orldwerb omfrerb etherb oolestcerb Erbferb Atinlerb anslatortrerb!");
///
///assert_eq!(translate_ferb_ascii("This library can translate any English text. It can even handle multiple sentences!"),
/// "Istherb ibrarylerb ancerb anslatetrerb anyferb Englishferb extterb. Itferb ancerb evenferb andleherb ultiplemerb entencesserb!"
///);
///
///assert_eq!(translate_ferb_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!"),
/// "Etlerb's ytrerb omeserb edgeferb asescerb. Attherb isferb aferb ontractioncerb, asferb ellwerb asferb aferb ordwerb erewherb etherb onlyferb owelverb isferb yferb. Eatnerb, allferb attherb orkswerb!"
///);
///assert_eq!(translate_ferb_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz"),
/// "Atwherb ifferb aferb ordwerb asherb onerb owelsverb, ikelerb istherb: bcdfghjklmnpqrstvwxzerb"
///);
///assert_eq!(translate_ferb_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!"),
/// "Oolcerb, oserb etherb euristicsherb akemerb ettyprerb oodgerb uessesgerb ithwerb atwherb eytherb're edferb!"
///);
///
///assert_eq!(translate_ferb_ascii("Hello-world"), "Elloherb-orldwerb");
///assert_eq!(translate_ferb_ascii("Hyphens-are-difficult-aren't-they?"), "Yphensherb-areferb-ifficultderb-arenferb't-eytherb?");
///```
pub fn translate_ferb_ascii(english: &str) -> String {
return translate_with_style_ascii(english, "erb", "ferb");
}
///Translates a multi-word string (including punctuation) into a custom-styled play language!
///
///Pass the string you wish to translate, the suffix you wish to have appended to most words, and the suffix
///you wish to have appended in various special-cases (such as when a word is only one letter or starts with a vowel).
///
///NOTE: The suffixes must be entirely lower-case or weird results may occur.
///
///# Examples
///
///```
///use anslatortray::translate_with_style;
///
///let suffix = "ancy";
///let special_case_suffix = "fancy";
///assert_eq!(translate_with_style("Hello world from the coolest Pig Latin translator!", suffix, special_case_suffix),
/// "Ellohancy orldwancy omfrancy ethancy oolestcancy Igpancy Atinlancy anslatortrancy!"
///);
///
///assert_eq!(translate_with_style("This library can translate any English text. It can even handle multiple sentences!", suffix, special_case_suffix),
/// "Isthancy ibrarylancy ancancy anslatetrancy anyfancy Englishfancy exttancy. Itfancy ancancy evenfancy andlehancy ultiplemancy entencessancy!"
///);
///
///assert_eq!(translate_with_style("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!", suffix, special_case_suffix),
/// "Etl".to_string() + suffix + "'s ytr" + suffix + " omes" + suffix + " edge" + special_case_suffix + " asesc" + suffix + ". Atth" + suffix + " is" + special_case_suffix + " a" +
/// special_case_suffix + " ontractionc" + suffix + ", as" + special_case_suffix + " ellw" + suffix + " as" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix +
/// " erewh" + suffix + " eth" + suffix + " only" + special_case_suffix + " owelv" + suffix + " is" + special_case_suffix + " y" + special_case_suffix + ". Eatn" + suffix + ", all" +
/// special_case_suffix + " atth" + suffix + " orksw" + suffix + "!"
///);
///
///assert_eq!(translate_with_style("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz", suffix, special_case_suffix),
/// "Atwh".to_string() + suffix + " if" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix + " ash" + suffix + " on" + suffix + " owelsv" + suffix + ", ikel" + suffix + " isth" + suffix + ": bcdfghjklmnpqrstvwxz" + suffix
///);
///
///assert_eq!(translate_with_style("Cool, so the heuristics make pretty good guesses with what they're fed!", suffix, special_case_suffix),
/// "Oolc".to_string() + suffix + ", os" + suffix + " eth" + suffix + " euristicsh" + suffix + " akem" + suffix + " ettypr" + suffix + " oodg" + suffix + " uessesg" + suffix + " ithw" + suffix + " atwh" + suffix + " eyth" + suffix + "'re edf" + suffix + "!"
///);
///
///assert_eq!(translate_with_style("Hello-world", suffix, special_case_suffix), "Elloh".to_string() + suffix + "-orldw" + suffix);
///
///assert_eq!(translate_with_style("Hyphens-are-difficult-aren't-they?", suffix, special_case_suffix),
/// "Yphensh".to_string() + suffix + "-are" + special_case_suffix + "-ifficultd" + suffix + "-aren" + special_case_suffix + "'t-eyth" + suffix + "?"
///);
///```
pub fn translate_with_style(english: &str, suffix_lower: &str, special_case_suffix_lower: &str) -> String {
if english.is_empty() {
return String::new();
}
//Convert the suffix and special_case_suffix we were provided to uppercase for words that are capitalized
let mut suffix_upper = String::with_capacity(suffix_lower.len());
for letter in suffix_lower.chars() {
suffix_upper.push(letter.to_ascii_uppercase());
}
let mut special_case_suffix_upper = String::with_capacity(special_case_suffix_lower.len());
for letter in special_case_suffix_lower.chars() {
special_case_suffix_upper.push(letter.to_ascii_uppercase());
}
let mut pig_latin_string = String::with_capacity(english.len() * 2);//Plenty of headroom in case the words are very small or the suffixes are long
let mut current_word = String::with_capacity(64);//Longer than all English words to avoid unneeded allocations (plus leaving room for leading and trailing extra characters)
let mut contraction_suffix = String::with_capacity(64);
let mut in_word: bool = false;
let mut in_contraction_suffix: bool = false;
//Buffers for improved performance (avoid repeated heap allocations)
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
for character in english.chars().peekable() {
if in_word {
if character.is_alphabetic() {
//Save the character to translate once the word ends; we also keep apostrophes so that translate_word_with_style can handle contractions
if in_contraction_suffix {
contraction_suffix.push(character);
} else {
current_word.push(character);
}
} else if character == '\'' {
in_contraction_suffix = true;
contraction_suffix.push(character);
} else {
//The word ended, so translate the chararacters we've saved up until this point!
in_word = false;
translate_word_with_style_reuse_buffers (
current_word.as_str(),
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper,
&mut pig_latin_string, &mut starting_consonants_buffer
);
//Push the contraction
in_contraction_suffix = false;
pig_latin_string.push_str(&contraction_suffix);
contraction_suffix.truncate(0);//Faster than creating a new string
//Append the symbol/whitespace we just got after the translated word
pig_latin_string.push(character);
}
} else {//We are not currently in a word
if character.is_alphabetic() {
//If we see a letter, we are in a word, so save the character for now so we can translate the word later
in_word = true;
current_word.truncate(0);//Faster than creating a new string
current_word.push(character);
} else {
//Otherwise copy symbols and whitespace as-is
pig_latin_string.push(character);
}
}
}
//If we ended on a word, we translate it and push it to the end of the string
if in_word {
translate_word_with_style_reuse_buffers (
current_word.as_str(),
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper,
&mut pig_latin_string, &mut starting_consonants_buffer
);
}
return pig_latin_string;
}
///Translates a multi-word string (including punctuation) into a custom-styled play language (Faster, but ASCII-only)!
///
///Faster than [`translate_with_style()`], but requires that the string only contains ASCII characters or else it may panic.
///
///Pass the string you wish to translate, the suffix you wish to have appended to most words, and the suffix
///you wish to have appended in various special-cases (such as when a word is only one letter or starts with a vowel).
///
///NOTE: The suffixes must be entirely lower-case or weird results may occur.
///
///# Examples
///
///```
///use anslatortray::translate_with_style_ascii;
///
///let suffix = "ancy";
///let special_case_suffix = "fancy";
///assert_eq!(translate_with_style_ascii("Hello world from the coolest Pig Latin translator!", suffix, special_case_suffix),
/// "Ellohancy orldwancy omfrancy ethancy oolestcancy Igpancy Atinlancy anslatortrancy!"
///);
///
///assert_eq!(translate_with_style_ascii("This library can translate any English text. It can even handle multiple sentences!", suffix, special_case_suffix),
/// "Isthancy ibrarylancy ancancy anslatetrancy anyfancy Englishfancy exttancy. Itfancy ancancy evenfancy andlehancy ultiplemancy entencessancy!"
///);
///
///assert_eq!(translate_with_style_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!", suffix, special_case_suffix),
/// "Etl".to_string() + suffix + "'s ytr" + suffix + " omes" + suffix + " edge" + special_case_suffix + " asesc" + suffix + ". Atth" + suffix + " is" + special_case_suffix + " a" +
/// special_case_suffix + " ontractionc" + suffix + ", as" + special_case_suffix + " ellw" + suffix + " as" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix +
/// " erewh" + suffix + " eth" + suffix + " only" + special_case_suffix + " owelv" + suffix + " is" + special_case_suffix + " y" + special_case_suffix + ". Eatn" + suffix + ", all" +
/// special_case_suffix + " atth" + suffix + " orksw" + suffix + "!"
///);
///
///assert_eq!(translate_with_style_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz", suffix, special_case_suffix),
/// "Atwh".to_string() + suffix + " if" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix + " ash" + suffix + " on" + suffix + " owelsv" + suffix + ", ikel" + suffix + " isth" + suffix + ": bcdfghjklmnpqrstvwxz" + suffix
///);
///
///assert_eq!(translate_with_style_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!", suffix, special_case_suffix),
/// "Oolc".to_string() + suffix + ", os" + suffix + " eth" + suffix + " euristicsh" + suffix + " akem" + suffix + " ettypr" + suffix + " oodg" + suffix + " uessesg" + suffix + " ithw" + suffix + " atwh" + suffix + " eyth" + suffix + "'re edf" + suffix + "!"
///);
///
///assert_eq!(translate_with_style_ascii("Hello-world", suffix, special_case_suffix), "Elloh".to_string() + suffix + "-orldw" + suffix);
///
///assert_eq!(translate_with_style_ascii("Hyphens-are-difficult-aren't-they?", suffix, special_case_suffix),
/// "Yphensh".to_string() + suffix + "-are" + special_case_suffix + "-ifficultd" + suffix + "-aren" + special_case_suffix + "'t-eyth" + suffix + "?"
///);
///```
pub fn translate_with_style_ascii(english: &str, suffix_lower: &str, special_case_suffix_lower: &str) -> String {
if english.is_empty() {
return String::new();
}
//TODO switch to fully operating on u8 slices/arrays/Vecs internally (converting from a string, then to a string at the end) in anslatortray 0.5.0
let mut pig_latin_string = String::with_capacity(english.len() * 2);//Plenty of headroom in case the words are very small or the suffixes are long
//Convert the suffix and special_case_suffix we were provided to uppercase for words that are capitalized
let mut suffix_upper = String::with_capacity(suffix_lower.len());
for letter in suffix_lower.chars() {
suffix_upper.push(letter.to_ascii_uppercase());
}
let mut special_case_suffix_upper = String::with_capacity(special_case_suffix_lower.len());
for letter in special_case_suffix_lower.chars() {
special_case_suffix_upper.push(letter.to_ascii_uppercase());
}
//Flags used to remember if we're currently processing a word, contraction, contraction suffix or neither
let mut in_word: bool = false;
let mut in_contraction_suffix: bool = false;
//Buffer for improved performance (avoid repeated heap allocations)
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
//Indexes for improved performance (avoid copying characters to use as the english_word argument for translate_word_with_style_reuse_buffers)
//However, this assumes each character is one byte, so this only works with ASCII strings
let mut slice_start_index: usize = 0;//Inclusive
let mut slice_end_index: usize = 0;//Exclusive
for character in english.chars() {
if in_word {
if in_contraction_suffix {
if character.is_alphabetic() {
//We never translate the contraction suffix of a word, so just copy remaining letters as-is
} else {
//The contraction ended, and so too does the word
//We still want to copy the non-letter to the output though
in_contraction_suffix = false;
in_word = false;
}
pig_latin_string.push(character);//Copy the character
slice_start_index += 1;//Keep the slice start index up to speed for later use
} else {
if character.is_alphabetic() {
//This character is part of the word, so increment the slice_end_index to include it in the slice
slice_end_index += 1;
} else {
//The word or first part of the contraction ended, so translate the word we've identified up until this point!
let word_slice: &str = &english[slice_start_index..slice_end_index];
translate_word_with_style_reuse_buffers_ascii (
word_slice,
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper,
&mut pig_latin_string, &mut starting_consonants_buffer
);
//Bring the slice_start_index to the end since we've finished the word and need it ready for the next one
slice_start_index = slice_end_index + 1;
//Append the symbol/whitespace we just got after the translated word
pig_latin_string.push(character);
//If the symbol/whitespace we just got is an apostrophe, then this is a contraction suffix
if character == '\'' {
in_contraction_suffix = true;
} else {
in_word = false;//This wasn't a contraction, so we're done with the word
}
}
}
} else {
if character.is_alphabetic() {
//If we see a letter, we are in a word, so set the slice_end_index to the character after the slice_start_index
in_word = true;
slice_end_index = slice_start_index + 1;
} else {
//Otherwise copy symbols and whitespace as-is
pig_latin_string.push(character);
slice_start_index += 1;
}
}
}
//If we ended on a word (but not on a contraction suffix), we translate it and push it to the end of the string
if in_word && !in_contraction_suffix {
let word_slice: &str = &english[slice_start_index..slice_end_index];
translate_word_with_style_reuse_buffers_ascii (
word_slice,
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper,
&mut pig_latin_string, &mut starting_consonants_buffer
);
}
return pig_latin_string;
}
/* Tests */
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_translate_with_style() {
let suffix_special_case_suffix_pairs = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
for pair in suffix_special_case_suffix_pairs {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_with_style("Hello world from the coolest Pig Latin translator!", suffix, special_case_suffix),
"Elloh".to_string() + suffix + " orldw" + suffix + " omfr" + suffix + " eth" + suffix + " oolestc" + suffix + " Igp" + suffix + " Atinl" + suffix + " anslatortr" + suffix + "!"
);
assert_eq!(translate_with_style("This library can translate any English text. It can even handle multiple sentences!", suffix, special_case_suffix),
"Isth".to_string() + suffix + " ibraryl" + suffix + " anc" + suffix + " anslatetr" + suffix + " any" + special_case_suffix + " English" + special_case_suffix + " extt" + suffix +
". It" + special_case_suffix + " anc" + suffix + " even" + special_case_suffix + " andleh" + suffix + " ultiplem" + suffix + " entencess" + suffix + "!"
);
}
}
#[test]
fn test_translate_with_style_edgecases() {
let suffix_special_case_suffix_pairs = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
for pair in suffix_special_case_suffix_pairs {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_with_style("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!", suffix, special_case_suffix),
"Etl".to_string() + suffix + "'s ytr" + suffix + " omes" + suffix + " edge" + special_case_suffix + " asesc" + suffix + ". Atth" + suffix + " is" + special_case_suffix + " a" +
special_case_suffix + " ontractionc" + suffix + ", as" + special_case_suffix + " ellw" + suffix + " as" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix +
" erewh" + suffix + " eth" + suffix + " only" + special_case_suffix + " owelv" + suffix + " is" + special_case_suffix + " y" + special_case_suffix + ". Eatn" + suffix + ", all" +
special_case_suffix + " atth" + suffix + " orksw" + suffix + "!"
);
assert_eq!(translate_with_style("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ", suffix, special_case_suffix),
"Atwh".to_string() + suffix + " if" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix + " ash" + suffix + " on" + suffix + " owelsv" + suffix + ", ikel" + suffix + " isth" + suffix + ": bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ" + suffix
);
assert_eq!(translate_with_style("Cool, so the heuristics make pretty good guesses with what they're fed!", suffix, special_case_suffix),
"Oolc".to_string() + suffix + ", os" + suffix + " eth" + suffix + " euristicsh" + suffix + " akem" + suffix + " ettypr" + suffix + " oodg" + suffix + " uessesg" + suffix + " ithw" + suffix + " atwh" + suffix + " eyth" + suffix + "'re edf" + suffix + "!"
);
assert_eq!(translate_with_style("Hello-world", suffix, special_case_suffix), "Elloh".to_string() + suffix + "-orldw" + suffix);
assert_eq!(translate_with_style("Hyphens-are-difficult-aren't-they?", suffix, special_case_suffix),
"Yphensh".to_string() + suffix + "-are" + special_case_suffix + "-ifficultd" + suffix + "-aren" + special_case_suffix + "'t-eyth" + suffix + "?"
);
}
}
#[test]
fn test_translate_with_style_uppercase() {
let suffix_special_case_suffix_lower_upper_tuples = [
("ay", "way", "AY", "WAY"), ("ay", "yay", "AY", "YAY"), ("ay", "hay", "AY", "HAY"), ("erb", "ferb", "ERB", "FERB"),
("ancy", "fancy", "ANCY", "FANCY"), ("orange", "porange", "ORANGE", "PORANGE"),
("anana", "banana", "ANANA", "BANANA"), ("atin", "latin", "ATIN", "LATIN"), ("ust", "rust", "UST", "RUST"),
];
for pair in suffix_special_case_suffix_lower_upper_tuples {
let suffix_lower = pair.0;
let special_case_suffix_lower = pair.1;
let suffix_upper = pair.2;
let special_case_suffix_upper = pair.3;
assert_eq!(translate_with_style("HELLO WORLD!", suffix_lower, special_case_suffix_lower),
"ELLOH".to_string() + suffix_upper + " ORLDW" + suffix_upper + "!"
);
assert_eq!(translate_with_style("ISN't THIS COOL?", suffix_lower, special_case_suffix_lower),
"ISN".to_string() + special_case_suffix_upper + "'t ISTH" + suffix_upper + " OOLC" + suffix_upper + "?"
);
assert_eq!(translate_with_style("What ABOUT a MIX?", suffix_lower, special_case_suffix_lower),
"Atwh".to_string() + suffix_lower + " ABOUT" + special_case_suffix_upper + " a" + special_case_suffix_lower + " IXM" + suffix_upper + "?"
);
assert_eq!(translate_with_style("Luke, I am your father!", suffix_lower, special_case_suffix_lower),//We don't want to capitalize single-letter words
"Ukel".to_string() + suffix_lower + ", I" + special_case_suffix_lower+ " am" + special_case_suffix_lower + " oury" + suffix_lower + " atherf" + suffix_lower + "!"
);
}
}
#[test]
fn test_translate_ferb_uppercase() {
}
#[test]
fn test_translate_with_style_ascii() {
let suffix_special_case_suffix_pairs = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
for pair in suffix_special_case_suffix_pairs {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_with_style_ascii("Hello world from the coolest Pig Latin translator!", suffix, special_case_suffix),
"Elloh".to_string() + suffix + " orldw" + suffix + " omfr" + suffix + " eth" + suffix + " oolestc" + suffix + " Igp" + suffix + " Atinl" + suffix + " anslatortr" + suffix + "!"
);
assert_eq!(translate_with_style_ascii("This library can translate any English text. It can even handle multiple sentences!", suffix, special_case_suffix),
"Isth".to_string() + suffix + " ibraryl" + suffix + " anc" + suffix + " anslatetr" + suffix + " any" + special_case_suffix + " English" + special_case_suffix + " extt" + suffix +
". It" + special_case_suffix + " anc" + suffix + " even" + special_case_suffix + " andleh" + suffix + " ultiplem" + suffix + " entencess" + suffix + "!"
);
}
}
#[test]
fn test_translate_with_style_ascii_edgecases() {
let suffix_special_case_suffix_pairs = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
for pair in suffix_special_case_suffix_pairs {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_with_style_ascii("Let's try some edge cases. That is a contraction, as well as a word where the only vowel is y. Neat, all that works!", suffix, special_case_suffix),
"Etl".to_string() + suffix + "'s ytr" + suffix + " omes" + suffix + " edge" + special_case_suffix + " asesc" + suffix + ". Atth" + suffix + " is" + special_case_suffix + " a" +
special_case_suffix + " ontractionc" + suffix + ", as" + special_case_suffix + " ellw" + suffix + " as" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix +
" erewh" + suffix + " eth" + suffix + " only" + special_case_suffix + " owelv" + suffix + " is" + special_case_suffix + " y" + special_case_suffix + ". Eatn" + suffix + ", all" +
special_case_suffix + " atth" + suffix + " orksw" + suffix + "!"
);
assert_eq!(translate_with_style_ascii("What if a word has no vowels, like this: bcdfghjklmnpqrstvwxz", suffix, special_case_suffix),
"Atwh".to_string() + suffix + " if" + special_case_suffix + " a" + special_case_suffix + " ordw" + suffix + " ash" + suffix + " on" + suffix + " owelsv" + suffix + ", ikel" + suffix + " isth" + suffix + ": bcdfghjklmnpqrstvwxz" + suffix
);
assert_eq!(translate_with_style_ascii("Cool, so the heuristics make pretty good guesses with what they're fed!", suffix, special_case_suffix),
"Oolc".to_string() + suffix + ", os" + suffix + " eth" + suffix + " euristicsh" + suffix + " akem" + suffix + " ettypr" + suffix + " oodg" + suffix + " uessesg" + suffix + " ithw" + suffix + " atwh" + suffix + " eyth" + suffix + "'re edf" + suffix + "!"
);
assert_eq!(translate_with_style_ascii("Hello-world", suffix, special_case_suffix), "Elloh".to_string() + suffix + "-orldw" + suffix);
assert_eq!(translate_with_style_ascii("Hyphens-are-difficult-aren't-they?", suffix, special_case_suffix),
"Yphensh".to_string() + suffix + "-are" + special_case_suffix + "-ifficultd" + suffix + "-aren" + special_case_suffix + "'t-eyth" + suffix + "?"
);
}
}
#[test]
fn test_translate_with_style_ascii_uppercase() {
let suffix_special_case_suffix_lower_upper_tuples = [
("ay", "way", "AY", "WAY"), ("ay", "yay", "AY", "YAY"), ("ay", "hay", "AY", "HAY"), ("erb", "ferb", "ERB", "FERB"),
("ancy", "fancy", "ANCY", "FANCY"), ("orange", "porange", "ORANGE", "PORANGE"),
("anana", "banana", "ANANA", "BANANA"), ("atin", "latin", "ATIN", "LATIN"), ("ust", "rust", "UST", "RUST"),
];
for pair in suffix_special_case_suffix_lower_upper_tuples {
let suffix_lower = pair.0;
let special_case_suffix_lower = pair.1;
let suffix_upper = pair.2;
let special_case_suffix_upper = pair.3;
assert_eq!(translate_with_style_ascii("HELLO WORLD!", suffix_lower, special_case_suffix_lower),
"ELLOH".to_string() + suffix_upper + " ORLDW" + suffix_upper + "!"
);
assert_eq!(translate_with_style_ascii("ISN't THIS COOL?", suffix_lower, special_case_suffix_lower),
"ISN".to_string() + special_case_suffix_upper + "'t ISTH" + suffix_upper + " OOLC" + suffix_upper + "?"
);
assert_eq!(translate_with_style_ascii("What ABOUT a MIX?", suffix_lower, special_case_suffix_lower),
"Atwh".to_string() + suffix_lower + " ABOUT" + special_case_suffix_upper + " a" + special_case_suffix_lower + " IXM" + suffix_upper + "?"
);
assert_eq!(translate_with_style_ascii("Luke, I am your father!", suffix_lower, special_case_suffix_lower),//We don't want to capitalize single-letter words
"Ukel".to_string() + suffix_lower + ", I" + special_case_suffix_lower+ " am" + special_case_suffix_lower + " oury" + suffix_lower + " atherf" + suffix_lower + "!"
);
}
}
}
/* Benches */
#[cfg_attr(feature = "nightly-features", cfg(test))]
#[cfg(feature = "nightly-features")]
mod benches {
extern crate test;
use test::Bencher;
use super::*;
const PROJECT_DESCRIPTION: &str = "A simple Rust library to translate from English to Pig Latin!";
const LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
#[bench]
fn way_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate(PROJECT_DESCRIPTION); });
}
#[bench]
fn yay_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_yay(PROJECT_DESCRIPTION); });
}
#[bench]
fn hay_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_hay(PROJECT_DESCRIPTION); });
}
#[bench]
fn ferb_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_ferb(PROJECT_DESCRIPTION); });
}
#[bench]
fn way_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate(LOREM_IPSUM); });
}
#[bench]
fn yay_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_yay(LOREM_IPSUM); });
}
#[bench]
fn hay_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_hay(LOREM_IPSUM); });
}
#[bench]
fn ferb_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_ferb(LOREM_IPSUM); });
}
#[bench]
fn ascii_way_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_ascii(PROJECT_DESCRIPTION); });
}
#[bench]
fn ascii_yay_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_yay_ascii(PROJECT_DESCRIPTION); });
}
#[bench]
fn ascii_hay_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_hay_ascii(PROJECT_DESCRIPTION); });
}
#[bench]
fn ascii_ferb_project_description(b: &mut Bencher) {
b.iter(|| -> String { return translate_ferb_ascii(PROJECT_DESCRIPTION); });
}
#[bench]
fn ascii_way_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_ascii(LOREM_IPSUM); });
}
#[bench]
fn ascii_yay_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_yay_ascii(LOREM_IPSUM); });
}
#[bench]
fn ascii_hay_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_hay_ascii(LOREM_IPSUM); });
}
#[bench]
fn ascii_ferb_lorem_ipsum(b: &mut Bencher) {
b.iter(|| -> String { return translate_ferb_ascii(LOREM_IPSUM); });
}
}

@ -1,482 +0,0 @@
/* translate_words.rs
* Copyright (C) 2022 John Jekel
* See the LICENSE file at the root of the project for licensing info.
*
* Contains functions to translate individual words (used by translate_strings.rs)
*
*/
/* Imports */
use crate::helpers::{is_vowel, is_y, word_is_uppercase, word_is_uppercase_ascii};
/* Functions */
pub(crate) fn translate_word_with_style_reuse_buffers (
english_word: &str,
suffix_lower: &str, special_case_suffix_lower: &str, suffix_upper: &str, special_case_suffix_upper: &str,
buffer_to_append_to: &mut String, starting_consonants: &mut String
) {
if english_word.is_empty() {
return;
}
if english_word.len() == 1 {
buffer_to_append_to.push_str(english_word);
buffer_to_append_to.push_str(special_case_suffix_lower);
return;
}
let mut iterator = english_word.chars().peekable();
//Check the first letter
let first_letter: char = iterator.next().unwrap();
//Check if the word is uppercase
let word_uppercase = word_is_uppercase(&english_word);
//As a herustic, we consider Y to be a vowel when it is not at the start of the word
//However, if any word is only one letter long, this takes priority and the word is treated like a vowel
let first_letter_was_vowel: bool = {
is_vowel(first_letter)//Not including y
|| if let Some(character) = iterator.peek() { !character.is_alphabetic() } else { true }//Non-alphabetic character after the first letter, or the word ends after the first letter
};
starting_consonants.truncate(0);
if first_letter_was_vowel {
buffer_to_append_to.push(first_letter);
} else {
let first_char_was_upper = first_letter.is_ascii_uppercase();
starting_consonants.push(if word_uppercase { first_letter } else { first_letter.to_ascii_lowercase() });
//Grab all of the starting consonants, and push the first vowel we enounter to buffer_to_append_to
loop {
match iterator.next() {
None => { break; },//The word has no vowels, but it is a herustic to pass it on so that ex. the acroynm binary code decimal or bcd becomes bcdway, etc.
Some(character) => {
if character.is_alphabetic() {
if is_vowel(character) || is_y(character) {//As a herustic, we consider Y to be a vowel when it is not at the start of the word
//The vowel is the first letter of the word; we want it match the capitalization of the first letter of the original word
if first_char_was_upper {
buffer_to_append_to.push(character.to_ascii_uppercase());
} else {
buffer_to_append_to.push(character.to_ascii_lowercase());
}
break;
} else {
starting_consonants.push(character);
}
} else {//The word ended without vowels or we met an apostrophe
break;//It is a herustic to pass it on so that ex. the letter y becomes yway, the word a becomes away, etc.
}
}
}
}
}
//Copy all of the remaining letters up to the end of the word
loop {
match iterator.next() {
None => { break; },//End of the word
Some(character) => { buffer_to_append_to.push(character); }
}
}
//Copy starting consonants and add the suffix, or add the special_case_suffix depending on the circumstances
if first_letter_was_vowel {
if word_uppercase {
buffer_to_append_to.push_str(special_case_suffix_upper);
} else {
buffer_to_append_to.push_str(special_case_suffix_lower);
}
} else {
buffer_to_append_to.push_str(&starting_consonants);
if word_uppercase {
buffer_to_append_to.push_str(suffix_upper);
} else {
buffer_to_append_to.push_str(suffix_lower);
}
}
}
pub(crate) fn translate_word_with_style_reuse_buffers_ascii (
english_word: &str,
suffix_lower: &str, special_case_suffix_lower: &str, suffix_upper: &str, special_case_suffix_upper: &str,
buffer_to_append_to: &mut String, starting_consonants: &mut String
) {
if english_word.is_empty() {
return;
}
if english_word.len() == 1 {
buffer_to_append_to.push_str(english_word);
buffer_to_append_to.push_str(special_case_suffix_lower);
return;
}
//TODO more ascii optimizations
let mut iterator = english_word.chars().peekable();
//Check the first letter
let first_letter: char = iterator.next().unwrap();
//Check if the word is uppercase
let word_uppercase = word_is_uppercase_ascii(&english_word);
//As a herustic, we consider Y to be a vowel when it is not at the start of the word
//However, if any word is only one letter long, this takes priority and the word is treated like a vowel
let first_letter_was_vowel: bool = {
is_vowel(first_letter)//Not including y
|| if let Some(character) = iterator.peek() { !character.is_alphabetic() } else { true }//Non-alphabetic character after the first letter, or the word ends after the first letter
};
starting_consonants.truncate(0);
if first_letter_was_vowel {
buffer_to_append_to.push(first_letter);
} else {
let first_char_was_upper = first_letter.is_ascii_uppercase();
starting_consonants.push(if word_uppercase { first_letter } else { first_letter.to_ascii_lowercase() });
//Grab all of the starting consonants, and push the first vowel we enounter to buffer_to_append_to
loop {
match iterator.next() {
None => { break; },//The word has no vowels, but it is a herustic to pass it on so that ex. the acroynm binary code decimal or bcd becomes bcdway, etc.
Some(character) => {
if character.is_alphabetic() {
if is_vowel(character) || is_y(character) {//As a herustic, we consider Y to be a vowel when it is not at the start of the word
//The vowel is the first letter of the word; we want it match the capitalization of the first letter of the original word
if first_char_was_upper {
buffer_to_append_to.push(character.to_ascii_uppercase());
} else {
buffer_to_append_to.push(character.to_ascii_lowercase());
}
break;
} else {
starting_consonants.push(character);
}
} else {//The word ended without vowels or we met an apostrophe
break;//It is a herustic to pass it on so that ex. the letter y becomes yway, the word a becomes away, etc.
}
}
}
}
}
//Copy all of the remaining letters up to the end of the word
loop {
match iterator.next() {
None => { break; },//End of the word
Some(character) => { buffer_to_append_to.push(character); }
}
}
//Copy starting consonants and add the suffix, or add the special_case_suffix depending on the circumstances
if first_letter_was_vowel {
if word_uppercase {
buffer_to_append_to.push_str(special_case_suffix_upper);
} else {
buffer_to_append_to.push_str(special_case_suffix_lower);
}
} else {
buffer_to_append_to.push_str(&starting_consonants);
if word_uppercase {
buffer_to_append_to.push_str(suffix_upper);
} else {
buffer_to_append_to.push_str(suffix_lower);
}
}
}
/* Tests */
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_translate_word_with_style() {
let suffix_special_case_suffix_pairs = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
for pair in suffix_special_case_suffix_pairs {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_word_with_style("Hello", suffix, special_case_suffix), "Elloh".to_string() + suffix);
assert_eq!(translate_word_with_style("World", suffix, special_case_suffix), "Orldw".to_string() + suffix);
assert_eq!(translate_word_with_style("This", suffix, special_case_suffix), "Isth".to_string() + suffix);
assert_eq!(translate_word_with_style("is", suffix, special_case_suffix), "is".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style("a", suffix, special_case_suffix), "a".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style("test", suffix, special_case_suffix), "estt".to_string() + suffix);
assert_eq!(translate_word_with_style("of", suffix, special_case_suffix), "of".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style("the", suffix, special_case_suffix), "eth".to_string() + suffix);
assert_eq!(translate_word_with_style("function", suffix, special_case_suffix), "unctionf".to_string() + suffix);
assert_eq!(translate_word_with_style("translate", suffix, special_case_suffix), "anslatetr".to_string() + suffix);
assert_eq!(translate_word_with_style("word", suffix, special_case_suffix), "ordw".to_string() + suffix);
assert_eq!(translate_word_with_style("I", suffix, special_case_suffix), "I".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style("Love", suffix, special_case_suffix), "Ovel".to_string() + suffix);
assert_eq!(translate_word_with_style("Pig", suffix, special_case_suffix), "Igp".to_string() + suffix);
assert_eq!(translate_word_with_style("Latin", suffix, special_case_suffix), "Atinl".to_string() + suffix);
assert_eq!(translate_word_with_style("You", suffix, special_case_suffix), "Ouy".to_string() + suffix);//Y isn't a vowel here
assert_eq!(translate_word_with_style("should", suffix, special_case_suffix), "ouldsh".to_string() + suffix);
assert_eq!(translate_word_with_style("try", suffix, special_case_suffix), "ytr".to_string() + suffix);//Y is a vowel here
assert_eq!(translate_word_with_style("yougurt", suffix, special_case_suffix), "ougurty".to_string() + suffix);//Y isn't a vowel here
//assert_eq!(translate_word_with_style("it's", suffix, special_case_suffix), "it".to_string() + special_case_suffix + "'s");//Contraction
assert_eq!(translate_word_with_style("quite", suffix, special_case_suffix), "uiteq".to_string() + suffix);//Awful to pronounce, but correct
assert_eq!(translate_word_with_style("nice", suffix, special_case_suffix), "icen".to_string() + suffix);
}
}
#[test]
fn test_translate_word_with_style_ascii() {
let suffix_special_case_suffix_pairs = [
("ay", "way"), ("ay", "yay"), ("ay", "hay"), ("erb", "ferb"), ("ancy", "fancy"), ("orange", "porange"), ("anana", "banana"), ("atin", "latin"), ("ust", "rust")
];
for pair in suffix_special_case_suffix_pairs {
let suffix = pair.0;
let special_case_suffix = pair.1;
assert_eq!(translate_word_with_style_ascii("Hello", suffix, special_case_suffix), "Elloh".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("World", suffix, special_case_suffix), "Orldw".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("This", suffix, special_case_suffix), "Isth".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("is", suffix, special_case_suffix), "is".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style_ascii("a", suffix, special_case_suffix), "a".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style_ascii("test", suffix, special_case_suffix), "estt".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("of", suffix, special_case_suffix), "of".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style_ascii("the", suffix, special_case_suffix), "eth".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("function", suffix, special_case_suffix), "unctionf".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("translate", suffix, special_case_suffix), "anslatetr".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("word", suffix, special_case_suffix), "ordw".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("I", suffix, special_case_suffix), "I".to_string() + special_case_suffix);
assert_eq!(translate_word_with_style_ascii("Love", suffix, special_case_suffix), "Ovel".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("Pig", suffix, special_case_suffix), "Igp".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("Latin", suffix, special_case_suffix), "Atinl".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("You", suffix, special_case_suffix), "Ouy".to_string() + suffix);//Y isn't a vowel here
assert_eq!(translate_word_with_style_ascii("should", suffix, special_case_suffix), "ouldsh".to_string() + suffix);
assert_eq!(translate_word_with_style_ascii("try", suffix, special_case_suffix), "ytr".to_string() + suffix);//Y is a vowel here
assert_eq!(translate_word_with_style_ascii("yougurt", suffix, special_case_suffix), "ougurty".to_string() + suffix);//Y isn't a vowel here
//assert_eq!(translate_word_with_style_ascii("it's", suffix, special_case_suffix), "it".to_string() + special_case_suffix + "'s");//Contraction
assert_eq!(translate_word_with_style_ascii("quite", suffix, special_case_suffix), "uiteq".to_string() + suffix);//Awful to pronounce, but correct
assert_eq!(translate_word_with_style_ascii("nice", suffix, special_case_suffix), "icen".to_string() + suffix);
}
}
fn translate_word_with_style(english_word: &str, suffix_lower: &str, special_case_suffix_lower: &str) -> String {
let mut suffix_upper = String::with_capacity(suffix_lower.len());
for letter in suffix_lower.chars() {
suffix_upper.push(letter.to_ascii_uppercase());
}
let mut special_case_suffix_upper = String::with_capacity(special_case_suffix_lower.len());
for letter in special_case_suffix_lower.chars() {
special_case_suffix_upper.push(letter.to_ascii_uppercase());
}
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
translate_word_with_style_reuse_buffers (
english_word,
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper,
&mut pig_latin_word, &mut starting_consonants_buffer
);
return pig_latin_word;
}
fn translate_word_with_style_ascii(english_word: &str, suffix_lower: &str, special_case_suffix_lower: &str) -> String {
let mut suffix_upper = String::with_capacity(suffix_lower.len());
for letter in suffix_lower.chars() {
suffix_upper.push(letter.to_ascii_uppercase());
}
let mut special_case_suffix_upper = String::with_capacity(special_case_suffix_lower.len());
for letter in special_case_suffix_lower.chars() {
special_case_suffix_upper.push(letter.to_ascii_uppercase());
}
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
translate_word_with_style_reuse_buffers_ascii (
english_word,
suffix_lower, special_case_suffix_lower, &suffix_upper, &special_case_suffix_upper,
&mut pig_latin_word, &mut starting_consonants_buffer
);
return pig_latin_word;
}
}
/* Benches */
#[cfg_attr(feature = "nightly-features", cfg(test))]
#[cfg(feature = "nightly-features")]
mod benches {
extern crate test;
use test::Bencher;
use super::*;
#[bench]
fn way_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers (
word,
"ay", "way", "AY", "WAY",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn yay_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers (
word,
"ay", "yay", "AY", "YAY",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn hay_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers (
word,
"ay", "hay", "AY", "HAY",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn ferb_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers (
word,
"erb", "ferb", "ERB", "FERB",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn ascii_way_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers_ascii (
word,
"ay", "way", "AY", "WAY",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn ascii_yay_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers_ascii (
word,
"ay", "yay", "AY", "YAY",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn ascii_hay_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers_ascii (
word,
"ay", "hay", "AY", "HAY",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
#[bench]
fn ascii_ferb_the_word_translator(b: &mut Bencher) {
let mut pig_latin_word = String::with_capacity(64 * 2);//Longer than all English words to avoid unneeded allocations, times 2 to leave room for whitespace, symbols, and the suffix
let mut starting_consonants_buffer = String::with_capacity(64);//Longer than basically all English words to avoid unneeded allocations, plus the fact that this isn't the whole word
b.iter(|| {
let word = test::black_box("translator");
translate_word_with_style_reuse_buffers_ascii (
word,
"erb", "ferb", "ERB", "FERB",
&mut pig_latin_word, &mut starting_consonants_buffer
);
pig_latin_word.truncate(0);
});
eprintln!("{}", pig_latin_word);//To avoid optimizing things out
}
}
Loading…
Cancel
Save