From c5c49d36852ff2346d5bbd900cb64d1493635df9 Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+ttytm@users.noreply.github.com> Date: Mon, 24 Jun 2024 22:01:52 +0200 Subject: [PATCH] builtin: fix `assert 'JVM_PUBLIC_ACC'.camel_to_snake() == 'jvm_public_acc'` (#21722) --- vlib/builtin/string.v | 28 ++++++++++++++++++++-------- vlib/builtin/string_test.v | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 2c2c13e7d90836..4dcb9f6ac93f82 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -2647,26 +2647,38 @@ pub fn (s string) camel_to_snake() string { if s.len == 0 { return '' } - lower_first_char := if s[0] >= `A` && s[0] <= `Z` { s[0] + 32 } else { s[0] } if s.len == 1 { - return lower_first_char.ascii_str() + return s.to_lower() } mut b := unsafe { malloc_noscan(2 * s.len + 1) } - second_char := if s[1] >= `A` && s[1] <= `Z` { `_` } else { s[1] } + mut prev_is_upper := false + first_char, second_char := if s[0] >= `A` && s[0] <= `Z` { + lower_first_c := if s[0] >= `A` && s[0] <= `Z` { s[0] + 32 } else { s[0] } + lower_second_c := if s[1] >= `A` && s[1] <= `Z` { + prev_is_upper = true + s[1] + 32 + } else { + s[1] + } + lower_first_c, lower_second_c + } else { + lower_first_c := s[0] + second_c := if s[1] >= `A` && s[1] <= `Z` { u8(`_`) } else { s[1] } + lower_first_c, second_c + } unsafe { - b[0] = lower_first_char + b[0] = first_char b[1] = second_char } + mut pos := 2 mut prev_char := second_char - mut prev_is_upper := false mut lower_c := `_` mut c_is_upper := false - mut pos := 1 for i in pos .. s.len { c := s[i] c_is_upper = c >= `A` && c <= `Z` lower_c = if c_is_upper { c + 32 } else { c } - if prev_is_upper == false && c_is_upper { + if !prev_is_upper && c_is_upper { // aB => a_b, if prev has `_`, then do not add `_` unsafe { if b[pos - 1] != `_` { @@ -2674,7 +2686,7 @@ pub fn (s string) camel_to_snake() string { pos++ } } - } else if prev_is_upper && c_is_upper == false && c != `_` { + } else if prev_is_upper && !c_is_upper && c != `_` { // Ba => _ba, if prev has `_`, then do not add `_` unsafe { if b[pos - 2] != `_` { diff --git a/vlib/builtin/string_test.v b/vlib/builtin/string_test.v index 2ab4a6cf73edb0..0ecb67c853bb0f 100644 --- a/vlib/builtin/string_test.v +++ b/vlib/builtin/string_test.v @@ -1528,6 +1528,7 @@ fn test_camel_to_snake() { assert 'aaBbCcDD'.camel_to_snake() == 'aa_bb_cc_dd' assert 'BBaa'.camel_to_snake() == 'b_baa' assert 'aa_BB'.camel_to_snake() == 'aa_bb' + assert 'JVM_PUBLIC_ACC'.camel_to_snake() == 'jvm_public_acc' } fn test_snake_to_camel() {