From 559cc970732d80e3ec624c20da4f8aac219d6b2e Mon Sep 17 00:00:00 2001
From: Igor Aleksanov <popzxc@yandex.ru>
Date: Thu, 8 Oct 2020 08:33:35 +0300
Subject: [PATCH] Add to_upper_snake_case function to stdx

---
 crates/hir_ty/src/diagnostics/decl_check.rs          |  4 ++--
 .../decl_check/{str_helpers.rs => case_conv.rs}      |  3 +--
 crates/stdx/src/lib.rs                               | 12 ++++++++++--
 3 files changed, 13 insertions(+), 6 deletions(-)
 rename crates/hir_ty/src/diagnostics/decl_check/{str_helpers.rs => case_conv.rs} (98%)

diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 4c20921e5de..901ccc94f65 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -10,7 +10,7 @@
 //! - static items (e.g. `static FOO: u8 = 10;`)
 //! - match arm bindings (e.g. `foo @ Some(_)`)
 
-mod str_helpers;
+mod case_conv;
 
 use hir_def::{
     adt::VariantData,
@@ -29,7 +29,7 @@ use syntax::{
 
 use crate::{
     db::HirDatabase,
-    diagnostics::{decl_check::str_helpers::*, CaseType, IncorrectCase},
+    diagnostics::{decl_check::case_conv::*, CaseType, IncorrectCase},
 };
 
 pub(super) struct DeclValidator<'a, 'b: 'a> {
diff --git a/crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
similarity index 98%
rename from crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs
rename to crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
index 2e1468c4cd7..3800f2a6b35 100644
--- a/crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check/case_conv.rs
@@ -136,8 +136,7 @@ pub fn to_upper_snake_case(ident: &str) -> Option<String> {
     }
 
     // Normalize the string from whatever form it's in currently, and then just make it uppercase.
-    let upper_snake_case =
-        stdx::to_lower_snake_case(ident).chars().map(|c| c.to_ascii_uppercase()).collect();
+    let upper_snake_case = stdx::to_upper_snake_case(ident);
 
     if upper_snake_case == ident {
         // While we didn't detect the correct case at the beginning, there
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index b55de813ec5..59d89f47d1c 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -28,7 +28,7 @@ pub fn timeit(label: &'static str) -> impl Drop {
     Guard { label, start: Instant::now() }
 }
 
-pub fn to_lower_snake_case(s: &str) -> String {
+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() {
@@ -41,11 +41,19 @@ pub fn to_lower_snake_case(s: &str) -> String {
         }
         prev = true;
 
-        buf.push(c.to_ascii_lowercase());
+        buf.push(change_case(&c));
     }
     buf
 }
 
+pub fn to_lower_snake_case(s: &str) -> String {
+    to_snake_case(s, char::to_ascii_lowercase)
+}
+
+pub fn to_upper_snake_case(s: &str) -> String {
+    to_snake_case(s, char::to_ascii_uppercase)
+}
+
 pub fn replace(buf: &mut String, from: char, to: &str) {
     if !buf.contains(from) {
         return;