Sources/SwiftBuffet/Utilities.swift (86 lines of code) (raw):

import Foundation /// Maps a protocol buffer type to its corresponding Swift type. /// /// - Parameters: /// - type: The protocol buffer type as a string. /// - isMap: A boolean indicating if the type is a map type. Defaults to `false`. /// - Returns: The corresponding Swift type as a string. func swiftType(from type: String, with swiftPrefix: String) -> String { switch type { case "double": return "Double" case "float": return "Float" case "int32", "sint32", "sfixed32": return "Int" case "int64", "sint64", "sfixed64": return "Int" case "uint32", "fixed32": return "UInt" case "uint64", "fixed64": return "UInt" case "bool": return "Bool" case "string": return "String" case "bytes": return "Data" case "google.protobuf.Timestamp": return "Date" case "google.protobuf.Duration": return "TimeInterval" default: return "\(swiftPrefix)\(type)" // Handle nested messages and enums if needed } } /// An array of primitive protocol buffer types. var primitiveTypes = [ "double", "float", "sint32", "sfixed32", "sint64", "sfixed64", "fixed32", "fixed64", "bool", "string", "bytes" ] /// Converts a snake_case string to camelCase. /// /// - Parameter string: The snake_case string to be converted. /// - Returns: The camelCase version of the input string. func snakeToCamelCase(_ string: String) -> String { let components = string.split(separator: "_") guard let first = components.first else { return string.lowercased() } return components .dropFirst() .reduce(String(first).lowercased()) { $0 + $1.capitalized } } /// Strips the common prefix from a list of enum cases and converts them to camelCase. /// /// - Parameter cases: An array of `ProtoEnumCase` to be processed. /// - Returns: An array of `ProtoEnumCase` with the common prefix removed and names converted to camelCase. func stripCommonPrefix(from cases: [ProtoEnumCase]) -> [ProtoEnumCase] { let prefix = findCommonPrefix(in: cases.map { $0.name }) ?? "" return cases.map { enumCase in let removePrefix = enumCase.name.replacingOccurrences(of: prefix, with: "") let newName = snakeToCamelCase(removePrefix) return ProtoEnumCase( name: newName, value: enumCase.value ) } } /// Finds the common prefix in an array of strings. /// /// - Parameter strings: An array of strings to find the common prefix in. /// - Returns: The common prefix as a string, or `nil` if there is no common prefix. func findCommonPrefix(in strings: [String]) -> String? { guard var prefix = strings.first else { return nil } for string in strings { while !string.hasPrefix(prefix) { prefix = String(prefix.dropLast()) if prefix.isEmpty { return nil } } } return prefix } /// Reads the contents of a file. /// /// - Parameters: /// - filename: The name of the file to read. /// - file: The path to the file. Defaults to the current file path. /// - Returns: The contents of the file as a string, or `nil` if an error occurs. func readFileContents(filename: String, file: StaticString = #file) -> String? { let fileURL = URL(fileURLWithPath: "\(file)", isDirectory: false) let directoryURL = fileURL.deletingLastPathComponent() let targetFileURL = directoryURL.appendingPathComponent(filename) do { let fileContents = try String(contentsOf: targetFileURL) return fileContents } catch { print("Error reading file: \(error)") return nil } } extension String { func capitalizingFirstLetter() -> String { return prefix(1).capitalized + dropFirst() } mutating func capitalizeFirstLetter() { self = self.capitalizingFirstLetter() } }