Sources/SwiftBuffet/Models.swift (104 lines of code) (raw):

import Foundation /// Represents a protocol buffer message. struct ProtoMessage { /// The name of the message. let name: String /// The fields of the message. let fields: [ProtoField] /// The name of the parent message, if nested. let parentName: String? /// The full name of the message, including parent name if nested. var fullName: String { if let parentName { return "\(parentName).\(name)" } else { return name } } } /// Represents a field within a protocol buffer message. struct ProtoField { let swiftPrefix: String /// The name of the field. let name: String /// The type of the field. let type: String /// An optional comment describing the field. let comment: String? /// Indicates if the field is optional. let isOptional: Bool /// Indicates if the field is a repeated field. let isRepeated: Bool /// Indicates if the field is a map type. let isMap: Bool /// Indicates if the field has been marked as deprecated in the proto file. let isDeprecated: Bool /// The case-corrected name of the field, converted to camelCase. var caseCorrectName: String { var newName = snakeToCamelCase(name) if name.contains("_url") { newName = newName.replacingOccurrences(of: "Url", with: "URL") } // if name.contains("_uri") { // newName = newName.replacingOccurrences(of: "Uri", with: "URL") // } if name.contains("_id") { newName = newName.replacingOccurrences(of: "Id", with: "ID") } return newName } var caseCorrectProtoName: String { var newName = snakeToCamelCase(name) if name.contains("_url") { newName = newName.replacingOccurrences(of: "Url", with: "URL") } // if name.contains("_uri") { // newName.replacingOccurrences(of: "Uri", with: "URL") // } if name.contains("_id") { newName = newName.replacingOccurrences(of: "Id", with: "ID") } if name == "description" { newName = "description_p" } return newName } /// The base type of the field, mapped to Swift types. var caseCorrectedBaseType: String { if isMap { // Skip map types since they are handled separately let mapTypes = type .dropFirst() .dropLast() .split(separator: ",") .map { $0.trimmingCharacters(in: .whitespaces) } let keyType = swiftType(from: String(mapTypes[0]), with: swiftPrefix) let valueType = swiftType(from: String(mapTypes[1]), with: swiftPrefix) return "[\(keyType): \(valueType)]" } else if isURL { return "URL" } else { return swiftType(from: type, with: swiftPrefix) } } var isURL: Bool { (caseCorrectName.uppercased().hasSuffix("URL") || caseCorrectName.uppercased().hasSuffix("URI")) && type == "string" } /// The fully case-corrected type of the field, including optional and repeated modifiers. var caseCorrectedType: String { let caseCorrectedType = caseCorrectedBaseType if isMap { // map types are handled by caseCorrectedBaseType return caseCorrectedType } else if isRepeated { return "[\(caseCorrectedType)]" } else if type == "bool" { return "Bool" // Bools should never be optional } else if isOptional { return "\(caseCorrectedType)?" } else { return "\(caseCorrectedType)" } } /// Indicates if the field is of a primitive type. var isPrimitiveType: Bool { if isMap { return false } else { return primitiveTypes.contains(type) } } } /// Represents a protocol buffer enum. struct ProtoEnum { /// The name of the enum. let name: String /// The cases of the enum. let cases: [ProtoEnumCase] /// The name of the parent message, if any. let parentName: String? /// The full name of the enum, including parent name if present. var fullName: String { if let parentName { return "\(parentName).\(name)" } else { return name } } } /// Represents a case within a protocol buffer enum. struct ProtoEnumCase { /// The name of the enum case. let name: String /// The value of the enum case. let value: Int }