this repo has no description
at main 56 lines 2.0 kB view raw
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}