Вы можете сделать Calendar.Component соответствующим протоколу OptionSet. Это позволит вам сохранить набор Calendar.Components с одним значением:
extension Calendar.Component: OptionSet, CaseIterable, Codable {
public init(rawValue: RawValue) {
switch rawValue {
case 1 << 0: self = .era
case 1 << 1: self = .year
case 1 << 2: self = .month
case 1 << 3: self = .day
case 1 << 4: self = .hour
case 1 << 5: self = .minute
case 1 << 6: self = .second
case 1 << 7: self = .weekday
case 1 << 8: self = .weekdayOrdinal
case 1 << 9: self = .quarter
case 1 << 10: self = .weekOfMonth
case 1 << 11: self = .weekOfYear
case 1 << 12: self = .yearForWeekOfYear
case 1 << 13: self = .nanosecond
case 1 << 14: self = .calendar
case 1 << 15: self = .timeZone
default: self = []
}
}
public var rawValue: Int {
switch self {
case .era: return 1 << 0
case .year: return 1 << 1
case .month: return 1 << 2
case .day: return 1 << 3
case .hour: return 1 << 4
case .minute: return 1 << 5
case .second: return 1 << 6
case .weekday: return 1 << 7
case .weekdayOrdinal: return 1 << 8
case .quarter: return 1 << 9
case .weekOfMonth: return 1 << 10
case .weekOfYear: return 1 << 11
case .yearForWeekOfYear: return 1 << 12
case .nanosecond: return 1 << 13
case .calendar: return 1 << 14
case .timeZone: return 1 << 15
}
}
public init() { self = [] }
public static let allCases: [Calendar.Component] = [
.era, .year, .month, .day, .hour, .minute, .second, .weekday, .weekdayOrdinal, .quarter, .weekOfMonth, .weekOfYear, .yearForWeekOfYear, .nanosecond, .calendar, .timeZone]
}
И реализуем инициализатор Set RawValue и свойство rawValue:
extension Set where Element: OptionSet & CaseIterable, Element.RawValue: FixedWidthInteger {
var rawValue: Element.RawValue {
var rawValue: Element.RawValue = .zero
for (index, element) in Element.allCases.enumerated() where contains(element) {
rawValue |= (1 << index)
}
return rawValue
}
init(rawValue: Element.RawValue) {
self.init()
for (index, element) in Element.allCases.enumerated()
where (rawValue & (1 << index)) != 0 {
insert(element)
}
}
}
Использование:
let componentSet: Set<Calendar.Component> = [.year, .month, .day]
let rawValue = componentSet.rawValue // 14
let loadedSet: Set<Calendar.Component> = .init(rawValue: rawValue) // [month, day, year]