Skip to content
Commits on Source (40)
[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>) {
......
This diff is collapsed.
/* 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"));
}
}
//!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};
This diff is collapsed.