// // Version.swift // InstanceFeatures // // Created by Shadowfacts on 5/14/23. // import Foundation @_spi(InstanceType) public struct Version: Equatable, Comparable, CustomStringConvertible { private static let regex = try! NSRegularExpression(pattern: "^(\\d+)\\.(\\d+)\\.(\\d+).*$") let major: Int let minor: Int let patch: Int init(_ major: Int, _ minor: Int, _ patch: Int) { self.major = major self.minor = minor self.patch = patch } init?(string: String) { guard let match = Version.regex.firstMatch(in: string, range: NSRange(location: 0, length: string.utf16.count)), match.numberOfRanges == 4 else { return nil } let majorStr = (string as NSString).substring(with: match.range(at: 1)) let minorStr = (string as NSString).substring(with: match.range(at: 2)) let patchStr = (string as NSString).substring(with: match.range(at: 3)) guard let major = Int(majorStr), let minor = Int(minorStr), let patch = Int(patchStr) else { return nil } self.major = major self.minor = minor self.patch = patch } public var description: String { "\(major).\(minor).\(patch)" } public static func ==(lhs: Version, rhs: Version) -> Bool { return lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.patch == rhs.patch } public static func <(lhs: Version, rhs: Version) -> Bool { if lhs.major < rhs.major { return true } else if lhs.major > rhs.major { return false } else if lhs.minor < rhs.minor { return true } else if lhs.minor > rhs.minor { return false } else if lhs.patch < rhs.patch { return true } else { return false } } } func <(lhs: Version?, rhs: Version) -> Bool { guard let lhs else { // nil is less than or equal to everything return true } return lhs < rhs } func >=(lhs: Version?, rhs: Version) -> Bool { guard let lhs else { // nil is less than or equal to everything return false } return lhs >= rhs }