Skip to content

Commit 2058f07

Browse files
committed
Handle multiple upcase letters
Example: Without change: `Recase.to_snake("SnakeACase") == "snake_acase"` With change: `Recase.to_snake("SnakeACase") == "snake_a_case"`
1 parent e5a8bc4 commit 2058f07

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

lib/recase/cases/generic.ex

+18-8
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,19 @@ defmodule Recase.Generic do
107107
end)
108108

109109
Enum.each(?A..?Z, fn char ->
110-
defp do_split(<<unquote(char), rest::binary>>, {"", acc}),
111-
do: do_split(rest, {<<unquote(char)::utf8>>, acc})
110+
defp do_split(<<unquote(char), _::binary>> = input, {"", acc}) do
111+
{upcase_streak, rest} = upcase_streak(input, "")
112+
113+
case byte_size(upcase_streak) do
114+
1 ->
115+
do_split(rest, {<<unquote(char)::utf8>>, acc})
112116

113-
defp do_split(<<unquote(char), rest::binary>>, {curr, acc}) do
114-
<<c::utf8, _::binary>> = String.reverse(curr)
117+
2 ->
118+
<<c1::utf8, c2::utf8>> = upcase_streak
119+
do_split(rest, {<<c2::utf8>>, [c1 | acc]})
115120

116-
if c in ?A..?Z do
117-
do_split(rest, {curr <> <<unquote(char)::utf8>>, acc})
118-
else
119-
do_split(rest, {<<unquote(char)::utf8>>, [curr | acc]})
121+
_ ->
122+
do_split(rest, {<<upcase_streak::binary>>, acc})
120123
end
121124
end
122125
end)
@@ -145,4 +148,11 @@ defmodule Recase.Generic do
145148
do_split(rest, {curr <> <<char::utf8>>, acc})
146149
end
147150
end
151+
152+
Enum.each(?A..?Z, fn char ->
153+
defp upcase_streak(<<unquote(char), rest::binary>>, curr),
154+
do: upcase_streak(rest, curr <> <<unquote(char)::utf8>>)
155+
end)
156+
157+
defp upcase_streak(rest, upcase_streak), do: {upcase_streak, rest}
148158
end

test/recase_test/snake_case_test.exs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ defmodule Recase.SnakeCaseTest do
1616
assert convert("--snake-case--") == "snake_case"
1717
assert convert("snake#case") == "snake_case"
1818
assert convert("snake?!case") == "snake_case"
19+
assert convert("SnakeACase") == "snake_a_case"
20+
assert convert("CurrencyISOCode") == "currency_i_s_o_code"
1921
end
2022

2123
test "should return single letter" do

0 commit comments

Comments
 (0)