Efficient line cropping

I have a csv file with a first column of data that represents an element code that optionally ends with "UNIUNI" or a mixed case of these characters downloaded using a barcode reader. I need to trim the last "UNI" s.

In Rust, I tried to write with partial success a function like this:

 fn main() { // Ok: from "9846UNIUNI" to "9846" println!("{}", read_csv_rilev("9846UNIUNI".to_string())); // Wrong: from "9846uniuni" to "9846" println!("{}", read_csv_rilev("9846uniuni".to_string())); } fn read_csv_rilev(code: String) -> String { code //.to_uppercase() /*Unstable feature in Rust 1.1*/ .trim_right_matches("UNI") .to_string() } 

The ideal function signature looks like this:

 fn read_csv_rilev(mut s: &String) {/**/} 

but probably in-place action in String is not a good idea. In fact, there is nothing to be done in the Rust standard library except String::pop() .

Is there a way to apply cropping on a String without highlighting another?

+6
source share
3 answers

way to apply cropping on String without highlighting another?

Yes, using truncate :

 const TRAILER: &'static str = "UNI"; fn read_csv_rilev(s: &mut String) { while s.ends_with(TRAILER) { let len = s.len(); let new_len = len.saturating_sub(TRAILER.len()); s.truncate(new_len); } } fn main() { let mut code = "Hello WorldUNIUNIUNI".into(); read_csv_rilev(&mut code); println!("{}", code); } 

Of course, you do not need to mess with the highlighted line at all. You can use the same logic and create consecutive substrings of a string. This basically works trim_right_matches , but a little less general:

 const TRAILER: &'static str = "UNI"; fn read_csv_rilev(mut s: &str) -> &str { while s.ends_with(TRAILER) { let len = s.len(); let new_len = len.saturating_sub(TRAILER.len()); s = &s[..new_len]; } s } fn main() { let code = "Hello WorldUNIUNIUNI"; let truncated = read_csv_rilev(code); println!("{}", truncated); } 

In general, I would probably go with a second solution.

+7
source

but probably in-place action in String is not a good idea.

The binding is changed to mut s: &String , and not to the string itself. You would take s: &mut String if you want to change the string itself.

However, I don't think this is something in the standard library for this.

+3
source

Another solution is to use the owning_ref container, which allows you to return both &str and its String support at the same time:

 extern crate owning_ref; use owning_ref::StringRef; fn read_csv_rilev(code: String) -> StringRef { StringRef::new(code).map(|s| s.trim_right_matches("UNI")) } 
+2
source

All Articles