https://stackoverflow.com/questions/38406793/why-is-capitalizing-the-first-letter-of-a-string-so-convoluted-in-rust Stack Overflow 1. About 2. Products 3. For Teams 1. Stack Overflow Public questions & answers 2. Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers 3. Jobs Programming & related technical career opportunities 4. Talent Recruit tech talent & build your employer brand 5. Advertising Reach developers & technologists worldwide 6. About the company [ ] Loading... 1. 2. Log in Sign up 3. current community + Stack Overflow help chat + Meta Stack Overflow your communities Sign up or log in to customize your list. more stack exchange communities company blog People who code: we want your input. Take the Survey Join Stack Overflow to learn, share knowledge, and build your career. Sign up with email Sign up Sign up with Google Sign up with GitHub Sign up with Facebook 1. Home 2. 1. Public 2. Questions 3. Tags 4. Users 5. Find a Job 6. Jobs 7. Companies 3. Teams Stack Overflow for Teams - Collaborate and share knowledge with a private group. [teams-illo-free-si] Create a free Team What is Teams? 1. Teams What's this? 2. Create free Team Teams Q&A for work Connect and share knowledge within a single location that is structured and easy to search. Learn more Why is capitalizing the first letter of a string so convoluted in Rust? Ask Question Asked 4 years, 10 months ago Active 9 months ago Viewed 14k times 88 16 I'd like to capitalize the first letter of a &str. It's a simple problem and I hope for a simple solution. Intuition tells me to do something like this: let mut s = "foobar"; s[0] = s[0].to_uppercase(); But &strs can't be indexed like this. The only way I've been able to do it seems overly convoluted. I convert the &str to an iterator, convert the iterator to a vector, upper case the first item in the vector, which creates an iterator, which I index into, creating an Option, which I unwrap to give me the upper-cased first letter. Then I convert the vector into an iterator, which I convert into a String, which I convert to a &str. let s1 = "foobar"; let mut v: Vec = s1.chars().collect(); v[0] = v[0].to_uppercase().nth(0).unwrap(); let s2: String = v.into_iter().collect(); let s3 = &s2; Is there an easier way than this, and if so, what? If not, why is Rust designed this way? Similar question string rust uppercase Share Follow edited May 23 '17 at 12:02 [a00] Community 111 silver badge asked Jul 16 '16 at 1:07 [b01] marshallmmarshallm 1,13511 gold badge88 silver badges99 bronze badges 5 * 52 It's a simple problem -- no, it's not. Please capitalize ss when interpreted as German. Hint: it's not a single character. Even the problem statement can be complicated. For example, it would be improper to capitalize the first character of the surname von Hagen. This is all an aspect of living in a global world that has had thousands of years of divergent cultures with different practices and we are trying to squash all those into 8 bits and 2 lines of code. - Shepmaster Jul 16 '16 at 1:13 * 3 What you pose seems to be a character encoding problem, not a data type problem. I presume char::to_uppercase already properly handles Unicode. My question is, why the need for all data type conversions? It seems indexing could return a multi-byte, Unicode character (not a single byte character, which would assume ascii only), and to_uppercase could return an upper case character in whatever language it's in, if one is available in said language. - marshallm Jul 16 '16 at 1:26 * 3 @marshallm char::to_uppercase indeed handles this problem, but you throw away its efforts by only taking the first code point (nth(0)) instead of all the code points that make up the capitalization - user395760 Jul 16 '16 at 9:26 * Character encoding is not a straightforward process as pointed out by Joel on Software: Unicode. - Nathan Jul 19 '16 at 12:40 * @Shepmaster, in general you are correct. It's a simple problem in English (the de facto standard base of programming languages and data formats). Yes there are scripts where "capitalization" is not even a concept, and others where it is very complicated. - Paul Draper Dec 4 '19 at 3:27 Add a comment | 6 Answers 6 Active Oldest Votes 110 Why is it so convoluted? Let's break it down, line-by-line let s1 = "foobar"; We've created a literal string that is encoded in UTF-8. UTF-8 allows us to encode the 1,114,112 code points of Unicode in a manner that's pretty compact if you come from a region of the world that types in mostly characters found in ASCII, a standard created in 1963. UTF-8 is a variable length encoding, which means that a single code point might take from 1 to 4 bytes. The shorter encodings are reserved for ASCII, but many Kanji take 3 bytes in UTF-8. let mut v: Vec = s1.chars().collect(); This creates a vector of characters. A character is a 32-bit number that directly maps to a code point. If we started with ASCII-only text, we've quadrupled our memory requirements. If we had a bunch of characters from the astral plane, then maybe we haven't used that much more. v[0] = v[0].to_uppercase().nth(0).unwrap(); This grabs the first code point and requests that it be converted to an uppercase variant. Unfortunately for those of us who grew up speaking English, there's not always a simple one-to-one mapping of a "small letter" to a "big letter". Side note: we call them upper- and lower-case because one box of letters was above the other box of letters back in the day. This code will panic when a code point has no corresponding uppercase variant. I'm not sure if those exist, actually. It could also semantically fail when a code point has an uppercase variant that has multiple characters, such as the German ss. Note that ss may never actually be capitalized in The Real World, this is the just example I can always remember and search for. As of 2017-06-29, in fact, the official rules of German spelling have been updated so that both "Ss" and "SS" are valid capitalizations! let s2: String = v.into_iter().collect(); Here we convert the characters back into UTF-8 and require a new allocation to store them in, as the original variable was stored in constant memory so as to not take up memory at run time. let s3 = &s2; And now we take a reference to that String. It's a simple problem Unfortunately, this is not true. Perhaps we should endeavor to convert the world to Esperanto? I presume char::to_uppercase already properly handles Unicode. Yes, I certainly hope so. Unfortunately, Unicode isn't enough in all cases. Thanks to huon for pointing out the Turkish I, where both the upper (I) and lower case (i) versions have a dot. That is, there is no one proper capitalization of the letter i; it depends on the locale of the the source text as well. why the need for all data type conversions? Because the data types you are working with are important when you are worried about correctness and performance. A char is 32-bits and a string is UTF-8 encoded. They are different things. indexing could return a multi-byte, Unicode character There may be some mismatched terminology here. A char is a multi-byte Unicode character. Slicing a string is possible if you go byte-by-byte, but the standard library will panic if you are not on a character boundary. One of the reasons that indexing a string to get a character was never implemented is because so many people misuse strings as arrays of ASCII characters. Indexing a string to set a character could never be efficient - you'd have to be able to replace 1-4 bytes with a value that is also 1-4 bytes, causing the rest of the string to bounce around quite a lot. to_uppercase could return an upper case character As mentioned above, ss is a single character that, when capitalized, becomes two characters. Solutions See also trentcl's answer which only uppercases ASCII characters. Original If I had to write the code, it'd look like: fn some_kind_of_uppercase_first_letter(s: &str) -> String { let mut c = s.chars(); match c.next() { None => String::new(), Some(f) => f.to_uppercase().chain(c).collect(), } } fn main() { println!("{}", some_kind_of_uppercase_first_letter("joe")); println!("{}", some_kind_of_uppercase_first_letter("jill")); println!("{}", some_kind_of_uppercase_first_letter("von Hagen")); println!("{}", some_kind_of_uppercase_first_letter("ss")); } But I'd probably search for uppercase or unicode on crates.io and let someone smarter than me handle it. Improved Speaking of "someone smarter than me", Veedrac points out that it's probably more efficient to convert the iterator back into a slice after the first capital codepoints are accessed. This allows for a memcpy of the rest of the bytes. fn some_kind_of_uppercase_first_letter(s: &str) -> String { let mut c = s.chars(); match c.next() { None => String::new(), Some(f) => f.to_uppercase().collect::() + c.as_str(), } } Share Follow edited Dec 3 '18 at 14:11 answered Jul 16 '16 at 1:31 [419] ShepmasterShepmaster 276k4747 gold badges735735 silver badges971971 bronze badges Is this answer outdated? Yes | No 13 * 37 After thinking about it a lot, I understand these design choices better. The standard library should choose the most versatile, performant, and safe trade-offs possible. Otherwise, it forces developers to make trade-offs that might not be appropriate for their application, architecture, or locale. Or it could lead to ambiguity and misunderstandings. If I prefer other trade-offs, I can choose a 3rd-party library or write it myself. - marshallm Jul 16 '16 at 3:56 * 14 @marshallm that's really great to hear! I fear that many newcomers to Rust misunderstand the decisions that the Rust designers have made and simply write them off as being too complicated for no benefit. By asking and answering questions here, I have gained an appreciation for the care that needs to go into such designs and hopefully become a better programmer. Keeping an open mind and being willing to learn more is a great trait to have as a programmer. - Shepmaster Jul 16 '16 at 13:50 * 6 The "Turkish i" is an example of locale dependence that is more directly relevant to this particular question than sorting. - huon Jul 18 '16 at 21:23 * 6 I'm surprised they have to_uppercase and to_lowercase but not to_titlecase. IIRC, some unicode characters actually have a special titlecase variant. - Tim Jul 18 '16 at 22:22 * 6 By the way, even a single code point may not be the right unit to convert. What if the first character is a grapheme cluster that should receive special handling when upper-casing? (It so happens that decomposed umlauts work if you just upper-case the base character, but I don't know if that is universally true.) - Sebastian Redl Jan 19 '18 at 13:40 | Show 8 more comments 24 Is there an easier way than this, and if so, what? If not, why is Rust designed this way? Well, yes and no. Your code is, as the other answer pointed out, not correct, and will panic if you give it something like bod-skd-l-. So doing this with Rust's standard library is even harder than you initially thought. However, Rust is designed to encourage code reuse and make bringing in libraries easy. So the idiomatic way to capitalize a string is actually quite palatable: extern crate inflector; use inflector::Inflector; let capitalized = "some string".to_title_case(); Share Follow answered Jun 17 '17 at 0:32 user8174234user8174234 Is this answer outdated? Yes | No 2 * 5 The question of the user sounds more like he would want .to_sentence_case(). - Christopher Oezbek Jun 15 '19 at 21:20 * 1 Sadly it doesn't help with naming things... This is awesome library and I never saw it before, but it's name is hard (for me) to remember and has functions that have hardly anything to do with actual inflection, one of them being your example. - Sahsahae Nov 28 '19 at 20:15 Add a comment | 12 It's not especially convoluted if you are able to limit your input to ASCII-only strings. Since Rust 1.23, str has a make_ascii_uppercase method (in older Rust versions, it was available through the AsciiExt trait). This means you can uppercase ASCII-only string slices with relative ease: fn make_ascii_titlecase(s: &mut str) { if let Some(r) = s.get_mut(0..1) { r.make_ascii_uppercase(); } } This will turn "taylor" into "Taylor", but it won't turn "edouard" into "Edouard". (playground) Use with caution. Share Follow edited Dec 1 '18 at 16:38 answered Dec 1 '18 at 14:43 [Fqd] trentcltrentcl 18k55 gold badges3737 silver badges6060 bronze badges Is this answer outdated? Yes | No 1 * 2 Help a Rust newbie out, why is r mutable? I see that s is a mutable str. Ohhhh ok: I have the answer for my own question: get_mut (called here w/ a range) explicitly returns Option<&mut>. - Steven Lu Apr 27 '19 at 17:25 Add a comment | 1 I did it this way: fn str_cap(s: &str) -> String { format!("{}{}", (&s[..1].to_string()).to_uppercase(), &s[1..]) } If it is not an ASCII string: fn str_cap(s: &str) -> String { format!("{}{}", s.chars().next().unwrap().to_uppercase(), s.chars().skip(1).collect::()) } Share Follow edited May 16 '20 at 9:43 answered Apr 18 '20 at 7:52 [AOh] Nikolai LasunovNikolai Lasunov 2122 bronze badges Is this answer outdated? Yes | No Add a comment | 0 This is how I solved this problem, notice I had to check if self is not ascii before transforming to uppercase. trait TitleCase { fn title(&self) -> String; } impl TitleCase for &str { fn title(&self) -> String { if !self.is_ascii() || self.is_empty() { return String::from(*self); } let (head, tail) = self.split_at(1); head.to_uppercase() + tail } } pub fn main() { println!("{}", "bruno".title()); println!("{}", "b".title()); println!("{}", "".title()); println!("{}", "ss".title()); println!("{}", "".title()); println!("{}", "bod-skd-l".title()); } Output Bruno B ss bod-skd-l Share Follow answered Aug 6 '20 at 3:44 [920] Bruno Rocha - rochacbrunoBruno Rocha - rochacbruno 6,66244 gold badges2323 silver badges3030 bronze badges Is this answer outdated? Yes | No 1 * Doesn't work if first character has two letters. - Markus Laire Apr 1 at 9:55 Add a comment | -1 Here's a version that is a bit slower than @Shepmaster's improved version, but also more idiomatic: fn capitalize_first(s: &str) -> String { let mut chars = s.chars(); chars .next() .map(|first_letter| first_letter.to_uppercase()) .into_iter() .flatten() .chain(chars) .collect() } Share Follow edited Jan 19 '20 at 8:29 answered Jan 16 '20 at 18:56 [fc7] yuyoyuppeyuyoyuppe 1,48222 gold badges1818 silver badges3030 bronze badges Is this answer outdated? Yes | No 0 Add a comment | Your Answer [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] Thanks for contributing an answer to Stack Overflow! * Please be sure to answer the question. Provide details and share your research! But avoid ... * Asking for help, clarification, or responding to other answers. * Making statements based on opinion; back them up with references or personal experience. To learn more, see our tips on writing great answers. Draft saved Draft discarded [ ] Sign up or log in Sign up using Google Sign up using Facebook Sign up using Email and Password Submit Post as a guest Name [ ] Email Required, but never shown [ ] Post as a guest Name [ ] Email Required, but never shown [ ] Post Your Answer Discard By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy Not the answer you're looking for? Browse other questions tagged string rust uppercase or ask your own question. The Overflow Blog * Using low-code tools to iterate products faster * Podcast 345: A good software tutorial explains the How. A great one explains... Featured on Meta * Take the 2021 Developer Survey Linked 2 Quick function to convert a String's first letter to uppercase? 80 What is the maximum number of bytes for a UTF-8 encoded character? 55 Get the String length in characters in Rust 22 Are all Kanji characters in UTF-8 3 bytes long? 17 How to get the last character of a &str? 15 Case-insensitive string matching in Rust 11 Unicode characters having asymmetric upper/lower case. Why? 3 How do I convert reverse domain notation to PascalCase? 2 What is an efficient way to compare strings while ignoring case? 1 How do I collect from multiple iterator types? See more linked questions Related 6915 What is the difference between String and string in C#? 3143 How do I iterate over the words of a string? 1617 How do I create a Java string from the contents of a file? 1024 Why can't I use switch statement on a String? 1879 Why is it string.join(list) instead of list.join(string)? 4175 How do I make the first letter of a string uppercase in JavaScript? 316 Converting string to title case 3593 Why is char[] preferred over String for passwords? 1669 How to check if the string is empty? 577 What are the differences between Rust's `String` and `str`? Hot Network Questions * Microcontroller bit information for the Core and different peripherals * How come full throttle is meaning full speed instead of the opposite? * How do I create an insert-only user for a Postgres table with an index? * Heating of hydraulic oil with hardtail electric MTB brakes * Why are most COB LEDs physically yellow? * Dealing with extremely inexperienced developers who have daily deadlines? * What did I just photograph? (rainbow way out of place) * Why was the neutrino thought to be massless? * Is LUKS still an effective option for consumer FDE considering Elcomsoft can break it? * Is there any country that jumped to developed status during the past 75 years after WW2? * How well would Max Faget's April 1, 1969 design for the Space Shuttle have actually worked? What would have been the major problems? * Linux backup script written in bash for tar * Extracting work from people who are on PIPs but who we also cannot fire? * Is Huang Yanling (a Wuhan virology researcher) the world's first COVID-19 patient? * Why did this gallon of milk stay fresh for so long? * Getting "Bye Bye Big Sur" error on installing Big Sur * What are the main reasons for using full justification when ragged right is more readable? * Former coworker I gave a reference for sabotaged the company on his last day - Should I update the reference contact with this new information? * How to remove the new weather info from the taskbar? * Is maximum speed a thing? * What is the DC of Draconic Presence? * How to get real-looking rust that will be safe to the touch? * What can US senators do against diversity trainings in the US Army? * Did I design my LED circuit correctly? more hot questions Question feed Subscribe to RSS Question feed To subscribe to this RSS feed, copy and paste this URL into your RSS reader. [https://stackoverflo] * lang-rust Stack Overflow * Questions * Jobs * Developer Jobs Directory * Salary Calculator * Help * Mobile Products * Teams * Talent * Advertising * Enterprise Company * About * Press * Work Here * Legal * Privacy Policy * Terms of Service * Contact Us * Cookie Settings * Cookie Policy Stack Exchange Network * Technology * Life / Arts * Culture / Recreation * Science * Other * Stack Overflow * Server Fault * Super User * Web Applications * Ask Ubuntu * Webmasters * Game Development * TeX - LaTeX * Software Engineering * Unix & Linux * Ask Different (Apple) * WordPress Development * Geographic Information Systems * Electrical Engineering * Android Enthusiasts * Information Security * Database Administrators * Drupal Answers * SharePoint * User Experience * Mathematica * Salesforce * ExpressionEngine(r) Answers * Stack Overflow em Portugues * Blender * Network Engineering * Cryptography * Code Review * Magento * Software Recommendations * Signal Processing * Emacs * Raspberry Pi * Stack Overflow na russkom * Code Golf * Stack Overflow en espanol * Ethereum * Data Science * Arduino * Bitcoin * Software Quality Assurance & Testing * Sound Design * Windows Phone * more (29) * Photography * Science Fiction & Fantasy * Graphic Design * Movies & TV * Music: Practice & Theory * Worldbuilding * Video Production * Seasoned Advice (cooking) * Home Improvement * Personal Finance & Money * Academia * Law * Physical Fitness * Gardening & Landscaping * Parenting * more (10) * English Language & Usage * Skeptics * Mi Yodeya (Judaism) * Travel * Christianity * English Language Learners * Japanese Language * Chinese Language * French Language * German Language * Biblical Hermeneutics * History * Spanish Language * Islam * Russkii iazyk * Russian Language * Arqade (gaming) * Bicycles * Role-playing Games * Anime & Manga * Puzzling * Motor Vehicle Maintenance & Repair * Board & Card Games * Bricks * Homebrewing * Martial Arts * The Great Outdoors * Poker * Chess * Sports * more (16) * MathOverflow * Mathematics * Cross Validated (stats) * Theoretical Computer Science * Physics * Chemistry * Biology * Computer Science * Philosophy * Linguistics * Psychology & Neuroscience * Computational Science * more (10) * Meta Stack Exchange * Stack Apps * API * Data * Blog * Facebook * Twitter * LinkedIn * Instagram site design / logo (c) 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.6.9.39464 Stack Overflow works best with JavaScript enabled [p-c1rF4kxg] Your privacy By clicking "Accept all cookies", you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy. Accept all cookies Customize settings