Home > OS >  trying to trim and lowercase my String in rust
trying to trim and lowercase my String in rust

Time:02-18

I'm trying to trim and lowercase my String.

Currently I have

use dialoguer::Input;

    let input : String = Input::new()
        .with_prompt("Guess a 5 letter word")
        .interact_text()
        .unwrap(); 
    let guess : &str = input.as_str(); // trim and lowercase

I'm trying to transform String into a trimmed and lowercased &str but some functions are only on &str and others only on String so I'm having trouble coming up with an elegant solution.

TL;DR: End goal have guess be a trimmed and lowercase &str

CodePudding user response:

Rust stdlib is not about elegance, but about correctness and efficiency.

In your particular case, trim() is defined as str::trim(&self) -> &str because it always returns a substring of the original string, so it does not need to copy or allocate a new string, just compute the begin and end, and do the slice.

But to_lowercase() is defined as str::to_lowercase(&self) -> String because it changes each of its characters to the lowercase equivalent, so it must allocate and fill a new String.

You may thing that if you own the string you can mutate it to lowercase in-place. But that will not work in general because there is not a 1-to-1 map between lowercase and uppercase letters. Think of, for example ß <-> SS in German.

Naturally, you may know that your string only has ASCII characters... if so you can also use str::make_ascii_lowercase(&mut self) that does the change in-place, but only for ASCII characters that do have the 1-to-1 map.

So, summing up, the more ergonomic code would be, to trim input and copy to an owned lowercase:

let guess : String = input.trim().to_lowercase();

Or if you absolutely want to avoid allocating an extra string, but you are positive that only ASCII characters matter:

let mut input = input; //you could also add the mut above
input.make_ascii_lowercase();
let guess: &str = input.trim();

CodePudding user response:

Try this:

let s = "   aBcD ";
let s2 = s.trim().to_lowercase();
println!("[{s}], [{s2}]");

The above will work if s is &str (as in my example) or String and it will print:

[   aBcD ], [abcd]

So the last line in your code (if you insist on having guess as &str) should become:

let guess: &str = &input.trim().to_lowercase();

Otherwise if you write just:

let guess = input.trim().to_lowercase();

, guess will be of type String, as that's what to_lowercase() returns.

  • Related