Skip to content

Commit d9b588b

Browse files
committed
simplify snakeCase transformer
1 parent 1313126 commit d9b588b

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

library/src/actions/toSnakeCase/helpers.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
1-
const SNAKE_CASE_SEPARATOR = '_';
1+
const snakeCaseSeparator = '_';
2+
3+
const separators = new Set([
4+
'', // represents all whitespaces (trim the character before performing the membership check)
5+
snakeCaseSeparator,
6+
'-',
7+
'.',
8+
]);
9+
10+
const isSeparator = (ch: string) => separators.has(ch.trim());
11+
12+
const isUpperCase = (ch: string) =>
13+
ch === ch.toUpperCase() && ch !== ch.toLowerCase();
14+
15+
const isNotEmpty = (arr: readonly unknown[]) => arr.length > 0;
16+
17+
const isTopSnakeCaseSeparator = (chs: readonly string[]) =>
18+
chs.at(-1) === snakeCaseSeparator;
219

320
/**
421
* Converts a string to snake case.
@@ -9,32 +26,29 @@ const SNAKE_CASE_SEPARATOR = '_';
926
*/
1027
export function snakeCase(input: string): string {
1128
const res: string[] = [];
12-
let wasPrevChUpperCase = false;
29+
let wasPrevUpperCase = false;
1330
for (const ch of input.trimStart()) {
14-
const lowerCaseCh = ch.toLowerCase();
15-
const isWhiteSpace = ch.trim() === '';
16-
const isSeparator =
17-
isWhiteSpace || ch === SNAKE_CASE_SEPARATOR || ch === '-' || ch === '.';
18-
const isUpperCase = ch === ch.toUpperCase() && ch !== lowerCaseCh;
19-
if (isSeparator) {
20-
if (res.length > 0 && res[res.length - 1] !== SNAKE_CASE_SEPARATOR) {
21-
res.push(SNAKE_CASE_SEPARATOR);
22-
}
23-
} else if (isUpperCase) {
31+
const isCurUpperCase = isUpperCase(ch);
32+
if (isCurUpperCase) {
2433
if (
25-
res.length > 0 &&
26-
res[res.length - 1] !== SNAKE_CASE_SEPARATOR &&
27-
!wasPrevChUpperCase
34+
isNotEmpty(res) &&
35+
!isTopSnakeCaseSeparator(res) &&
36+
!wasPrevUpperCase
2837
) {
29-
res.push(SNAKE_CASE_SEPARATOR);
38+
res.push(snakeCaseSeparator);
3039
}
31-
res.push(lowerCaseCh);
32-
} else {
40+
res.push(ch.toLowerCase());
41+
} else if (!isSeparator(ch)) {
42+
// `ch` is a lowercase character
3343
res.push(ch);
3444
}
35-
wasPrevChUpperCase = isUpperCase;
45+
// `ch` is a separator
46+
else if (isNotEmpty(res) && !isTopSnakeCaseSeparator(res)) {
47+
res.push(snakeCaseSeparator);
48+
}
49+
wasPrevUpperCase = isCurUpperCase;
3650
}
37-
if (res.length > 0 && res[res.length - 1] === SNAKE_CASE_SEPARATOR) {
51+
if (isTopSnakeCaseSeparator(res)) {
3852
res.pop();
3953
}
4054
return res.join('');

0 commit comments

Comments
 (0)