10480: fix: Change `stdx::to_snake_case` to match rustc implementation r=Veykril a=Crauzer

Fixes #10473

Co-authored-by: crauzer <filip.quitko@gmail.com>
This commit is contained in:
bors[bot] 2021-10-07 12:56:28 +00:00 committed by GitHub
commit 5191fb755b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 16 deletions

View File

@ -161,6 +161,7 @@ mod tests {
check(to_lower_snake_case, "lowerCamelCase", expect![["lower_camel_case"]]);
check(to_lower_snake_case, "a", expect![[""]]);
check(to_lower_snake_case, "abc", expect![[""]]);
check(to_lower_snake_case, "foo__bar", expect![["foo_bar"]]);
}
#[test]
@ -192,5 +193,7 @@ mod tests {
check(to_upper_snake_case, "A", expect![[""]]);
check(to_upper_snake_case, "ABC", expect![[""]]);
check(to_upper_snake_case, "X86_64", expect![[""]]);
check(to_upper_snake_case, "FOO_BAr", expect![["FOO_BAR"]]);
check(to_upper_snake_case, "FOO__BAR", expect![["FOO_BAR"]]);
}
}

View File

@ -102,8 +102,8 @@ fn some_fn() {
"#,
r#"
fn some_fn() {
let what_a_weird_formatting = 10;
another_func(what_a_weird_formatting);
let what_aweird_formatting = 10;
another_func(what_aweird_formatting);
}
"#,
);

View File

@ -1,4 +1,5 @@
//! Missing batteries for standard libraries.
use std::iter;
use std::{cmp::Ordering, ops, time::Instant};
mod macros;
@ -37,22 +38,44 @@ pub fn to_lower_snake_case(s: &str) -> String {
pub fn to_upper_snake_case(s: &str) -> String {
to_snake_case(s, char::to_ascii_uppercase)
}
fn to_snake_case<F: Fn(&char) -> char>(s: &str, change_case: F) -> String {
let mut buf = String::with_capacity(s.len());
let mut prev = false;
for c in s.chars() {
// `&& prev` is required to not insert `_` before the first symbol.
if c.is_ascii_uppercase() && prev {
// This check is required to not translate `Weird_Case` into `weird__case`.
if !buf.ends_with('_') {
buf.push('_');
}
}
prev = true;
buf.push(change_case(&c));
// Code partially taken from rust/compiler/rustc_lint/src/nonstandard_style.rs
// commit: 9626f2b
fn to_snake_case<F: Fn(&char) -> char>(mut s: &str, change_case: F) -> String {
let mut words = vec![];
// Preserve leading underscores
s = s.trim_start_matches(|c: char| {
if c == '_' {
words.push(String::new());
true
} else {
false
}
});
for s in s.split('_') {
let mut last_upper = false;
let mut buf = String::new();
if s.is_empty() {
continue;
}
for ch in s.chars() {
if !buf.is_empty() && buf != "'" && ch.is_uppercase() && !last_upper {
words.push(buf);
buf = String::new();
}
last_upper = ch.is_uppercase();
buf.extend(iter::once(change_case(&ch)));
}
words.push(buf);
}
buf
words.join("_")
}
pub fn replace(buf: &mut String, from: char, to: &str) {