this repo has no description
1//
2// String+SnakeCase.swift
3// URLQueryItemCoder
4//
5// Created by Kyle Hughes on 4/10/23.
6//
7
8private let snakeCaseSeparator: Character = "_"
9
10extension String {
11 /// Convert from "camelCaseKeys" to "snake_case_keys".
12 ///
13 /// Capital characters are determined by testing membership in `CharacterSet.uppercaseLetters` and
14 /// `CharacterSet.lowercaseLetters` (Unicode General Categories Lu and Lt).
15 ///
16 /// The conversion to lower case uses `Locale.system`, also known as the ICU "root" locale. This means the result
17 /// is consistent regardless of the current user's locale and language preferences.
18 ///
19 /// Converting from camel case to snake case:
20 /// 1. Splits words at the boundary of lower-case to upper-case
21 /// 2. Inserts `_` between words
22 /// 3. Lowercases the entire string
23 /// 4. Preserves starting and ending `_`.
24 ///
25 /// For example, `oneTwoThree` becomes `one_two_three`. `_oneTwoThree_` becomes `_one_two_three_`.
26 internal func convertToSnakeCase() -> Self {
27 guard !isEmpty else {
28 return String()
29 }
30
31 var previousCharacter: Character? = nil
32 var snakeCase: [Character] = []
33
34 for index in indices {
35 let currentCharacter = self[index]
36
37 if currentCharacter.isUppercase {
38 if let previousCharacter, previousCharacter.isLowercase {
39 snakeCase.append(snakeCaseSeparator)
40 } else {
41 let nextIndex = self.index(after: index)
42
43 if nextIndex != endIndex, self[nextIndex].isLowercase {
44 snakeCase.append(snakeCaseSeparator)
45 }
46 }
47 }
48
49 snakeCase.append(contentsOf: currentCharacter.lowercased())
50
51 previousCharacter = currentCharacter
52 }
53
54 return String(snakeCase)
55 }
56}