Added macro for easier usage

Updated docs
Added option to add seperator to the output
This commit is contained in:
Uttarayan Mondal
2021-03-08 18:40:51 +05:30
parent 64ceb37e43
commit 3dec2ba0d7
72 changed files with 1994 additions and 318 deletions
+30 -79
View File
@@ -13,14 +13,21 @@
//!extern crate ntext;
//!use ntext::to_text;
//!fn main() {
//! println!("{}",to_text(1312));
//! assert_eq!(to_text(1312),"onethousandthreehundredtwelve");
//! println!("{}",to_text!(1312));
//! assert_eq!(to_text!(1312),"onethousandthreehundredtwelve");
//! println!("{}",to_text!(7123));
//! assert_eq!(to_text!(7123," "),"seven thousand one hundred twenty three");
//!}
//!```
//! This fucntion will also return an empty string on input zero
//! This macro will also return an empty string on input zero
mod no_seperator;
mod seperator;
mod test;
/// Convert digit to text.
pub use no_seperator::to_text_no_seperator;
pub use seperator::to_text_with_seperator;
/// Convert digit to words in a string.
pub fn digit_to_text(digit: u8) -> Option<String> {
match digit {
0 => Some("".to_string()),
@@ -36,88 +43,32 @@ pub fn digit_to_text(digit: u8) -> Option<String> {
_ => None,
}
}
fn tens_place(tens: u8, ones: u8) -> Option<String> {
match tens {
0 => digit_to_text(ones),
1 => match ones {
0 => Some("ten".to_string()),
1 => Some("eleven".to_string()),
2 => Some("twelve".to_string()),
3 => Some("thirteen".to_string()),
4 => Some("fourteen".to_string()),
5 => Some("fifteen".to_string()),
6 => Some("sixteen".to_string()),
7 => Some("seventeen".to_string()),
8 => Some("eighteen".to_string()),
9 => Some("nineteen".to_string()),
_ => None,
},
d @ 2..=5 | d @ 8 => Some({
let mut buffer = String::new();
match d {
2 => buffer.push_str("twenty"),
3 => buffer.push_str("thirty"),
4 => buffer.push_str("forty"),
5 => buffer.push_str("fifty"),
8 => buffer.push_str("eighty"),
_ => (),
}
buffer.push_str(digit_to_text(ones).unwrap().as_str());
buffer
}),
d @ 6..=9 => Some({
let mut string = digit_to_text(d).unwrap() + "ty";
string.push_str(digit_to_text(ones).unwrap().as_str());
string
}),
_ => None,
fn place_value(number: u8, place: u8, seperator: Option<&str>) -> Option<String> {
let mut buffer = digit_to_text(number).unwrap();
if let Some(sep) = seperator {
if number != 0 {
buffer.push_str(sep)
}
}
}
fn place_value(number: u8, place: u8) -> Option<String> {
let mut value = digit_to_text(number).unwrap();
match place {
1 => (),
2 => (), //This should never happen as 2 is included in the tens_place_holders
3 => value.push_str("hundred"),
4 => value.push_str("thousand"),
3 => buffer.push_str("hundred"),
4 => buffer.push_str("thousand"),
5 => (), // Souldn't happen
6 => value.push_str("million"),
6 => buffer.push_str("million"),
_ => (),
};
Some(value)
Some(buffer)
}
/// Convert u32 to words in a string.
pub fn to_text(number: u32) -> String {
let mut numtext: String = String::new();
let mut last: Option<u8> = None;
let tens_place_holders: [u8; 2] = [2, 5];
let digits: Vec<u8> = number
.to_string()
.chars()
.map(|d| d.to_digit(10).unwrap() as u8)
.collect();
let mut place: u8 = digits.len() as u8;
for (_index, digit) in digits.iter().enumerate() {
if tens_place_holders.contains(&place) {
last = Some(*digit);
place -= 1;
continue;
}
if let Some(last_digit) = last {
println!("hello index {}", place);
numtext.push_str(tens_place(last_digit, *digit).unwrap().as_str());
if place > 2 {
numtext.push_str(place_value(0, place).unwrap().as_str());
}
last = None;
} else if *digit != 0 {
numtext.push_str(place_value(*digit, place).unwrap().as_str())
}
place -= 1;
}
numtext
/// Macro which supports both seperator and without it
#[macro_export]
macro_rules! to_text {
($number:expr) => {
ntext::to_text_no_seperator($number);
};
($number:expr, $seperator:expr) => {
ntext::to_text_with_seperator($number, $seperator);
};
}
+71
View File
@@ -0,0 +1,71 @@
use crate::{digit_to_text, place_value};
fn tens_place(tens: u8, ones: u8) -> Option<String> {
match tens {
0 => digit_to_text(ones),
1 => match ones {
0 => Some("ten".to_string()),
1 => Some("eleven".to_string()),
2 => Some("twelve".to_string()),
3 => Some("thirteen".to_string()),
4 => Some("fourteen".to_string()),
5 => Some("fifteen".to_string()),
6 => Some("sixteen".to_string()),
7 => Some("seventeen".to_string()),
8 => Some("eighteen".to_string()),
9 => Some("nineteen".to_string()),
_ => None,
},
d @ 2..=5 | d @ 8 => Some({
let mut buffer = String::new();
match d {
2 => buffer.push_str("twenty"),
3 => buffer.push_str("thirty"),
4 => buffer.push_str("forty"),
5 => buffer.push_str("fifty"),
8 => buffer.push_str("eighty"),
_ => (),
}
buffer.push_str(digit_to_text(ones).unwrap().as_str());
buffer
}),
d @ 6..=9 => Some({
let mut string = digit_to_text(d).unwrap() + "ty";
string.push_str(digit_to_text(ones).unwrap().as_str());
string
}),
_ => None,
}
}
/// Convert u32 to words in a string.
pub fn to_text_no_seperator(number: u32) -> String {
let mut numtext: String = String::new();
let mut last: Option<u8> = None;
let tens_place_holders: [u8; 2] = [2, 5];
let digits: Vec<u8> = number
.to_string()
.chars()
.map(|d| d.to_digit(10).unwrap() as u8)
.collect();
let mut place: u8 = digits.len() as u8;
for (_index, digit) in digits.iter().enumerate() {
if tens_place_holders.contains(&place) {
last = Some(*digit);
place -= 1;
continue;
}
if let Some(last_digit) = last {
numtext.push_str(tens_place(last_digit, *digit).unwrap().as_str());
if place > 2 {
numtext.push_str(place_value(0, place, None).unwrap().as_str());
}
last = None;
} else if *digit != 0 {
numtext.push_str(place_value(*digit, place, None).unwrap().as_str())
}
place -= 1;
}
numtext
}
+86
View File
@@ -0,0 +1,86 @@
use crate::{digit_to_text, place_value};
fn tens_place_seperator(tens: u8, ones: u8, seperator: &str) -> Option<String> {
match tens {
0 => digit_to_text(ones),
1 => match ones {
0 => Some("ten".to_string()),
1 => Some("eleven".to_string()),
2 => Some("twelve".to_string()),
3 => Some("thirteen".to_string()),
4 => Some("fourteen".to_string()),
5 => Some("fifteen".to_string()),
6 => Some("sixteen".to_string()),
7 => Some("seventeen".to_string()),
8 => Some("eighteen".to_string()),
9 => Some("nineteen".to_string()),
_ => None,
},
d @ 2..=5 | d @ 8 => Some({
let mut buffer = String::new();
match d {
2 => buffer.push_str("twenty"),
3 => buffer.push_str("thirty"),
4 => buffer.push_str("forty"),
5 => buffer.push_str("fifty"),
8 => buffer.push_str("eighty"),
_ => (),
}
buffer.push_str(seperator);
buffer.push_str(digit_to_text(ones).unwrap().as_str());
buffer
}),
d @ 6..=9 => Some({
let mut buffer = digit_to_text(d).unwrap() + "ty";
buffer.push_str(seperator);
buffer.push_str(digit_to_text(ones).unwrap().as_str());
buffer
}),
_ => None,
}
}
/// Convert u32 to words in a string seperated by a seperator.
pub fn to_text_with_seperator(number: u32, seperator: &str) -> String {
let mut numtext: String = String::new();
let mut last: Option<u8> = None;
let tens_place_holders: [u8; 2] = [2, 5];
let digits: Vec<u8> = number
.to_string()
.chars()
.map(|d| d.to_digit(10).unwrap() as u8)
.collect();
let mut place: u8 = digits.len() as u8;
for (_index, digit) in digits.iter().enumerate() {
if tens_place_holders.contains(&place) {
last = Some(*digit);
place -= 1;
continue;
}
if *digit != 0 && place != digits.len() as u8 && numtext != "" {
numtext.push_str(seperator);
}
if let Some(last_digit) = last {
numtext.push_str(
tens_place_seperator(last_digit, *digit, seperator)
.unwrap()
.as_str(),
);
if place > 2 {
numtext.push_str(seperator);
numtext.push_str(place_value(0, place, Some(seperator)).unwrap().as_str());
}
last = None;
} else if *digit != 0 {
numtext.push_str(
place_value(*digit, place, Some(seperator))
.unwrap()
.as_str(),
);
}
place -= 1;
}
numtext
}
+13 -10
View File
@@ -10,8 +10,7 @@ mod tests {
}
#[test]
fn numbers() {
use crate::to_text;
use crate::to_text_no_seperator as to_text;
assert_eq!(to_text(1), "one");
assert_eq!(to_text(10), "ten");
assert_eq!(to_text(100), "onehundred");
@@ -21,13 +20,17 @@ mod tests {
assert_eq!(to_text(12), "twelve");
}
#[test]
fn tens() {
use crate::tens_place;
assert_eq!(tens_place(1, 2).unwrap(), "twelve");
assert_eq!(tens_place(7, 6).unwrap(), "seventysix");
assert_eq!(tens_place(5, 7).unwrap(), "fiftyseven");
assert_eq!(tens_place(2, 3).unwrap(), "twentythree");
assert_eq!(tens_place(6, 9).unwrap(), "sixtynine");
assert_eq!(tens_place(0, 9).unwrap(), "nine");
fn numbers_seperator() {
use crate::to_text_with_seperator as to_text;
assert_eq!(to_text(103, "/"), "one/hundred/three");
assert_eq!(to_text(1000, "/"), "one/thousand");
assert_eq!(
to_text(12345, "/"),
"twelve/thousand/three/hundred/forty/five"
);
assert_eq!(
to_text(651243, "/"),
"six/million/fifty/one/thousand/two/hundred/forty/three"
);
}
}