That's not an OptionSet
though. If you have to specify the backing storage type anyway, why not macro-generate values for a property wrapper instead? (This compiles. I like the lack of explicit typing.)
struct ShippingOptions: OptionSet {
@Option(0) static var nextDay
@Option(after: _nextDay) static var secondDay
@Option(3) static var priority
@Option(after: _priority) static var standard
let rawValue: UInt8
}
/// An "option", represented by a single bit flag.
@propertyWrapper public struct OptionSetOption<Options: OptionSet>
where Options.RawValue: BinaryInteger {
public init(_ bitFlagIndex: Options.RawValue) {
wrappedValue = .init(rawValue: 1 << bitFlagIndex)
}
public let wrappedValue: Options
}
public extension OptionSetOption {
/// An option with the next higher bit flag.
init(after previous: Self) {
wrappedValue = .init(rawValue: previous.wrappedValue.rawValue << 1)
}
}
public extension OptionSet where RawValue: BinaryInteger {
typealias Option = OptionSetOption<Self>
}
Macro-fication would maybe be like
@Option static var nextDay
public extension OptionSetOption {
public init(_: MacroMagic = HoweverMacrosWork) {
self.init(🪄 as Options.RawValue)
}
}
(I still think this is all uglier than the tuple solution. It's probably a better use of time to switch to making it so that property wrappers can apply to multiple variables, integrating with variadic generics.)