import Foundation struct ImageGenerationJob { let image: String let type: FileType let maximumWidth: Int let maximumHeight: Int let quality: CGFloat init(image: String, type: FileType, maximumWidth: CGFloat, maximumHeight: CGFloat, quality: CGFloat = 0.7) { self.image = image self.type = type self.maximumWidth = Int(maximumWidth) self.maximumHeight = Int(maximumHeight) self.quality = quality } init(image: String, type: FileType, maximumWidth: Int, maximumHeight: Int, quality: CGFloat = 0.7) { self.image = image self.type = type self.maximumWidth = maximumWidth self.maximumHeight = maximumHeight self.quality = quality } var version: String { let fileName = image.fileNameAndExtension.fileName let prefix = "\(fileName)@\(maximumWidth)x\(maximumHeight)" return "\(prefix).\(type.fileExtension)" } static func imageSet(for image: String, maxWidth: Int, maxHeight: Int, quality: CGFloat = 0.7) -> [ImageGenerationJob] { let type = FileType(fileExtension: image.fileExtension) let width2x = maxWidth * 2 let height2x = maxHeight * 2 return [ .init(image: image, type: .avif, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality), .init(image: image, type: .avif, maximumWidth: width2x, maximumHeight: height2x, quality: quality), .init(image: image, type: .webp, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality), .init(image: image, type: .webp, maximumWidth: width2x, maximumHeight: height2x, quality: quality), .init(image: image, type: type, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality), .init(image: image, type: type, maximumWidth: width2x, maximumHeight: height2x, quality: quality) ] } } extension ImageGenerationJob: Equatable { static func == (lhs: ImageGenerationJob, rhs: ImageGenerationJob) -> Bool { lhs.version == rhs.version } } extension ImageGenerationJob: Hashable { func hash(into hasher: inout Hasher) { hasher.combine(version) } } extension ImageGenerationJob: Comparable { static func < (lhs: ImageGenerationJob, rhs: ImageGenerationJob) -> Bool { lhs.version < rhs.version } }