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
ACP: Add std::string::String::replace_and_count
and/or replace_with
#344
Comments
To me While we're improving |
Definitely, indeed, the level of generality/flexibility is
That makes sense to me, I guess the time not spent allocating would be worth the overhead of the |
We discussed this in last week's libs-api meeting. We thought However, the exact signature of In other words: impl String {
pub fn replace_with(&mut self, p: impl Pattern, f: impl FnMut(&str) -> &'uhh str); // lifetime issues
pub fn replace_with(&mut self, p: impl Pattern, f: impl FnMut(&str) -> String); // unnecessary allocations
pub fn replace_with(&mut self, p: impl Pattern, f: impl FnMut(&'uhh str, impl FnOnce(&str))); // lifetime issues again
pub fn replace_with(&mut self, p: impl Pattern, f: impl FnMut(ReplacableSubstring<'_>)); // maybe??
pub fn replace_with(&mut self, p: impl Pattern, f: impl FnMut(ReplacableSubstring<'_>) -> ControlFlow<()>); // starting to look complicated ..
} Considering how underpowered std's Anyway, we'd be interested to 1) hear your thoughts, and 2) see some real world use cases (that aren't already better solved by using e.g. the |
since impl String {
pub fn replace_with(&mut self, p: impl Pattern, f: F) -> Self
where F: FnMut(&str) -> R, R: AsRef<str>;
} (or even make it |
Hi, first of all, thanks for the detailed reply and consideration. What I had in mind was similar to the signature below, which is I think better solved using the Regex approach. enum StringOrStr<'a> {
String(String),
Str(&'a str),
}
fn replace_with<'a, P: Pattern<'a>>(&'a self, from: P, mut f: impl FnMut(&str) -> StringOrStr<'a>) -> String;
To be honest, I did not know that regex allowed for closures in the replacer. The code sample below solves the cases I had in mind. let s = re.replace_all(&s, |c: ®ex::Captures| {
println!("replacing {:?}", c.get(0).unwrap().as_str());
count += 1;
"hello"
}); Therefore I don't think my suggestion solves any problems unsolved by the Regex crate. The only remaining question is whether |
that's already in the standard library as |
Proposal
Add
std::string::String::replace_and_count
and/orreplace_with
and/orreplace_and
.Problem statement
Today, standart library String replacement method does not (1) creating any type of telemetric information such as the number of replacements, or (2) allow any type of dynamic computed pattern.
For (1), such telemetry information is useful for logging or validation purposes; for (2), dynamic computed patterns allow for more complex transformation now possible
str::replace
today.Motivating examples or use cases
Collection Use Case 1: Checking if count > 0 for source string validation. This is currently only achievable by doing a 2nd pass over the string, resulting in 2 full traversals in the worse case.
Collection Use Case 2: Logging the count/position of the first match/positions of all matches.
Dynamic Pattern Use Case 1: Randomizing certain patterns within the string for anonymization purposes.
Dynamic Pattern Use Case 2: Tagging each replacement with a count number.
Solution sketch
I propose 3 candidate API's.
API 1:(
replace_and_count
) This API changes the return type of the replace function into(String, usize)
from the previous String, the second parameter being the number of changes to the original variable.API 2:(
replace_with
) This API receives anFnMut
that will return a&str
instead of the current&str
and uses that. This API can be used for dynamic patterns.API 3:(
replace_and
) This API receives an additionalFnMut
that does not return a value for executing side effects, such as counting.Alternatives
In the Rust Internals Forum discussion where I posted the Pre-RFC, there was also the
replace_iter
suggestion that I did not fully understand.Links and related work
Rust Internals Discussion: https://internals.rust-lang.org/t/pre-rfc-std-replace-and-count/20320/7
A Reddit Question: https://www.reddit.com/r/rust/comments/m39ybn/how_to_count_string_replacements_idiomatically/
The text was updated successfully, but these errors were encountered: