Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Commas module performance improvement by using zero-copy concept and in place char remove for remove_commas_mut #10

Merged
merged 3 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/commas/add_commas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
/// // function:
/// use rust_persian_tools::commas::add_commas::add_commas;
/// assert_eq!(add_commas("30000000"), "30,000,000");
/// assert_eq!(add_commas(30000000), "30,000,000");
///
/// // method:
/// use crate::rust_persian_tools::commas::add_commas::AddCommas;
/// assert_eq!("30000000".add_commas(), "30,000,000");
/// assert_eq!(30000000.add_commas(), "30,000,000");
///
/// // method on your custom type:
/// struct YourCustomType;
Expand All @@ -20,20 +18,21 @@
/// }
/// }
/// ```
pub fn add_commas(str: impl ToString) -> String {
let mut str: String = str.to_string();
pub fn add_commas(inp: impl AsRef<str>) -> String {
let inp = inp.as_ref();
let comma_less = |c: &char| c != &',';

str = str.replace(',', "");
let mut result = String::new();

let end = str
let mut end = inp
.chars()
.filter(comma_less)
.position(|c| c == '.')
.unwrap_or_else(|| str.chars().count());
.unwrap_or_else(|| inp.chars().filter(comma_less).count());

for (i, ch) in str.chars().enumerate() {
let mut result = String::new();
for (i, ch) in inp.chars().filter(comma_less).enumerate() {
if end == i {
result.push_str(&str[end..str.chars().count()]);
end += inp.chars().filter(|c| c == &',').count();
result.push_str(&inp[end..inp.chars().count()]);
break;
}
if (end - i) % 3 == 0 && i != 0 {
Expand All @@ -49,7 +48,13 @@ pub trait AddCommas {
fn add_commas(&self) -> String;
}

impl<T: ToString + std::fmt::Display> AddCommas for T {
impl AddCommas for str {
fn add_commas(&self) -> String {
add_commas(self)
}
}

impl AddCommas for String {
fn add_commas(&self) -> String {
add_commas(self)
}
Expand Down
29 changes: 26 additions & 3 deletions src/commas/remove_commas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,23 @@
/// use crate::rust_persian_tools::commas::remove_commas::RemoveCommas;
/// assert_eq!("30,000,000".remove_commas(), "30000000".to_string());
/// ```
pub fn remove_commas(str: impl Into<String>) -> String {
let str: String = str.into();
str.replace(',', "")
pub fn remove_commas(str: impl AsRef<str>) -> String {
str.as_ref().replace(',', "")
}

/// Remove all commas in string\
/// 3,000,000 -> 3000000\
/// Example:
/// ```rust
/// // function:
/// use rust_persian_tools::commas::remove_commas::remove_commas_mut;
/// let mut input = String::from("30,000,000");
/// remove_commas_mut(&mut input);
/// assert_eq!(input, "30000000".to_string());
///
/// ```
pub fn remove_commas_mut(str: &mut String) {
str.retain(|c| c != ',')
}

pub trait RemoveCommas {
Expand All @@ -33,10 +47,19 @@ impl RemoveCommas for str {

#[cfg(test)]
mod tests {
use std::time::Instant;

use super::*;

#[test]
fn remove_commas_test() {
assert_eq!(remove_commas("30,000,000"), "30000000".to_string());
}

#[test]
fn remove_commas_mut_test() {
let mut input = String::from("30,000,000");
remove_commas_mut(&mut input);
assert_eq!(input, "30000000".to_string());
}
}