Skip to content

Instantly share code, notes, and snippets.

@Amzd
Last active February 24, 2025 20:45
Semantic Version decoding in Swift. Does not validate the identifier.
/// https://gist.github.com/Amzd/93f2e7b4712242ec4e17476146f528a2
public struct Version: Codable {
public var major: UInt
public var minor: UInt
public var patch: UInt
public var identifier: String?
public var stringValue: String {
"\(major).\(minor).\(patch)" + (identifier.flatMap { "-\($0)" } ?? "")
}
public init?(from string: String) {
let hyphenSplit = string.components(separatedBy: "-")
self.identifier = hyphenSplit.count > 1 ? hyphenSplit.dropFirst().joined(separator: "-") : nil
let versionPart = hyphenSplit.first ?? string
let versionSplit = versionPart.components(separatedBy: ".")
let versionNrs = versionSplit.compactMap(UInt.init)
guard versionSplit.count == 3, versionNrs.count == 3 else { return nil }
self.major = versionNrs[0]
self.minor = versionNrs[1]
self.patch = versionNrs[2]
}
public init(from decoder: any Decoder) throws {
guard let validVersion = Self(from: try String(from: decoder)) else {
throw DecodingError.dataCorruptedError(in: try decoder.singleValueContainer(), debugDescription: "Failed to decode version")
}
self = validVersion
}
public func encode(to encoder: any Encoder) throws {
try stringValue.encode(to: encoder)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment