1

In the rustlings, in `iterators2.rs', I need to capitalize the first letter of a word.

This is the code that I have

pub fn capitalize_first(input: &str) -> String {
    let mut c = input.chars();
    return match c.next() {
        None => String::new(),
        Some(first) => first.to_uppercase(),
    };
}

The issue I get is

  --> exercises/standard_library_types/iterators2.rs:13:24
   |
11 |       return match c.next() {
   |  ____________-
12 | |         None => String::new(),
   | |                 ------------- this is found to be of type `String`
13 | |         Some(first) => first.to_uppercase(),
   | |                        ^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
   | |                        |
   | |                        expected struct `String`, found struct `ToUppercase`
14 | |     };
   | |_____- `match` arms have incompatible types

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

Why does char.to_uppercase() return struct ToUppercase and not a capitalized char?

Lacrosse343
  • 491
  • 1
  • 3
  • 18
  • 1
    German is an example of a mainstream language where a [fairly common letter](https://en.wikipedia.org/wiki/%C3%9F) results in multiple-char uppercase: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=eeffcf17b98b6086b5c8a5fe71d4ca9f – user4815162342 Nov 14 '21 at 13:23
  • An extensive collection of solutions is [**here**](https://stackoverflow.com/questions/38406793/why-is-capitalizing-the-first-letter-of-a-string-so-convoluted-in-rust) to find. – Kaplan Nov 17 '21 at 13:49

3 Answers3

1

The reason why is that we are in a big world and Rust strings are encoded in UTF-8, allowing for different languages and characters to be encoded correctly. In some languages, a lowercase letter might be one character, but its uppercase form is two characters.

For this reason, char.to_uppercase() return an iterator that must be collected to get the appropriate result.

Some(first) => first.to_uppercase().collect() should fix this issue

Lacrosse343
  • 491
  • 1
  • 3
  • 18
1

char has function called to_ascii_uppercase()

let ascii = 'a';
let non_ascii = '❤';

assert_eq!('A', ascii.to_ascii_uppercase());
assert_eq!('❤', non_ascii.to_ascii_uppercase());

Visit https://doc.rust-lang.org/std/char/struct.ToUppercase.html

3HYXX
  • 21
  • 1
0

ToUppercase is an iterator, because the uppercase version of the character may be composed of several codepoints, as delnan pointed in the comments. You can convert that to a Vector of characters:

c.to_uppercase().collect::<Vec<_>>(); 
Peter Csala
  • 17,736
  • 16
  • 35
  • 75