Skip to content

Commit

Permalink
Rename options to cases. Fix path to cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
DnV1eX committed Dec 24, 2024
1 parent b71fac0 commit 5d510d5
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 100 deletions.
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ enum ShippingOption {
```
> [!NOTE]
> The macro generates a nested `Set` structure that conforms to the `OptionSet` protocol, using `Int` as the default raw value type and extracting options from the names of enum cases in the order of declaration.\
> It also generates the `all` property as an option composition, along with some other helper members.
> It also generates the `all` property as an option composition, along with some other helper structure members.
Then you can create a typealias, and extend the option set with additional composite options:
```Swift
Expand All @@ -37,17 +37,17 @@ extension ShippingOptions {
## Advanced usage
The macro also supports custom raw value types and indices:
```Swift
@EnumOptionSet<Int8> // OptionSet.RawValue = Int8
@EnumOptionSet<UInt8> // OptionSet.RawValue = UInt8
enum ShippingOption: Int {
case nextDay // Starting with index 0. (rawValue: 1 << 0)
case secondDay // Incrementing by 1. (rawValue: 1 << 1)
case priority = 3 // Skipping index 2. (rawValue: 1 << 3)
case standard // Continuing to increment. (rawValue: 1 << 4)
case nextDay // Starting with index 0. (rawValue: 1 << 0)
case secondDay // Incrementing by 1. (rawValue: 1 << 1)
case priority = 3 // Skipping index 2. (rawValue: 1 << 3)
case standard // Continuing to increment. (rawValue: 1 << 4)
}
```
> [!TIP]
> The `OptionSet.RawValue` type can also be declared as the macro's first argument `@EnumOptionSet(Int8.self)`.\
> Currently, an even shorter form `@EnumOptionSet(Int8)` works, but this may be a bug of the Swift syntax analyzer, so use it at your own risk.
> The `OptionSet.RawValue` type can also be declared as the macro's first argument `@EnumOptionSet(UInt8.self)`.\
> Currently, an even shorter form `@EnumOptionSet(UInt8)` works, but this may be a bug of the Swift syntax analyzer, so use it at your own risk.
> [!NOTE]
> Enum raw values that are expressed in ways other than integer literals, as well as associated values, are ignored.\
Expand All @@ -58,9 +58,9 @@ Specifically, it performs checks for duplicate indices and raw value overflow. A

Both of checks can be disabled with the `checkOverflow` attribute flag:
```Swift
@EnumOptionSet<Int8>(checkOverflow: false)
@EnumOptionSet<UInt8>(checkOverflow: false)
enum ShippingOption: Int {
case nextDay, secondDay, priority, standard = 8 // Option bit index 8 is out of range for 'Int8'.
case nextDay, secondDay, priority, standard = 8 // Option bit index 8 is out of range for 'UInt8'.
}
```
> [!NOTE]
Expand All @@ -76,13 +76,13 @@ ShippingOptions.express.debugDescription // "OptionSet(0b00000011)"
```
The `CustomStringConvertible` and `CustomDebugStringConvertible` protocol conformance can be disabled by setting the `generateDescription` attribute flag to `false`.

### Options
The `OptionSet` maintains a connection to the enum cases through the `options` property and initializer.
### Cases
The `OptionSet` maintains a connection to the enum through the `cases` property and initializer.
```Swift
let shippingOptions = ShippingOptions(options: [.secondDay, .priority])
shippingOptions.options // [ShippingOption.secondDay, ShippingOption.priority]
let shippingOptions = ShippingOptions(cases: [.secondDay, .priority])
shippingOptions.cases // [ShippingOption.secondDay, ShippingOption.priority]
```
These are not generated for enums with associated values.
These structure members are not generated for enums with associated values.

### Subscript
The macro contains an `OptionSet` extension for accessing options as boolean flags using subscript notation:
Expand Down
8 changes: 4 additions & 4 deletions Sources/EnumOptionSetClient/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import EnumOptionSet

//struct ShippingOptions: OptionSet {
// let rawValue: Int
// let rawValue: UInt8
//
// static let nextDay = Self(rawValue: 1 << 0)
// static let secondDay = Self(rawValue: 1 << 1)
Expand All @@ -23,7 +23,7 @@ import EnumOptionSet
// static let all: Self = [.express, .priority, .standard]
//}

@EnumOptionSet<Int8>
@EnumOptionSet<UInt8>
enum ShippingOption: Int {
case nextDay, secondDay, priority = 3, standard
}
Expand All @@ -41,5 +41,5 @@ assert(shippingOptions == [.express, .priority, .standard])
shippingOptions[.express].toggle()
assert(shippingOptions == [.priority, .standard])

shippingOptions = .init(options: [.secondDay, .priority])
assert(shippingOptions.options == [.secondDay, .priority])
shippingOptions = .init(cases: [.secondDay, .priority])
assert(shippingOptions.cases == [.secondDay, .priority])
42 changes: 21 additions & 21 deletions Sources/EnumOptionSetMacros/EnumOptionSetMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ public struct EnumOptionSetMacro: MemberMacro {
"""

// Generates static constants for set options.
let members = try enumeratedElementNames.map { index, name in
var member = try VariableDeclSyntax("\(accessModifier)static let \(raw: name) = Self(bitIndex: \(raw: index))")
member.leadingTrivia = "/// `\(enumeration.name.text).\(optionSetStructName)(rawValue: 1 << \(index))`\n"
return member
let options = try enumeratedElementNames.map { index, name in
var option = try VariableDeclSyntax("\(accessModifier)static let \(raw: name) = Self(bitIndex: \(raw: index))")
option.leadingTrivia = "/// `\(enumeration.name.text).\(optionSetStructName)(rawValue: 1 << \(index))` option.\n"
return option
}

// Generates a static constant for the combination of all set options if the name is not already used in one of the options.
Expand Down Expand Up @@ -258,32 +258,32 @@ public struct EnumOptionSetMacro: MemberMacro {
}
}

var options: VariableDeclSyntax?
var initOptions: InitializerDeclSyntax?
var cases: VariableDeclSyntax?
var initCases: InitializerDeclSyntax?
if !hasAssociatedValues {
// Generates a computed property returning an array of enum cases corresponding to the bit mask.
options = try VariableDeclSyntax("\(accessModifier)var options: [\(enumeration.name.trimmed)]") { """
[\(raw: caseElements.map { "(Self.\($0.name.text), ShippingOption.\($0.name.text))" }.joined(separator: ", "))].reduce(into: []) { result, option in
if contains(option.0) {
result.append(option.1)
cases = try VariableDeclSyntax("\(accessModifier)var cases: [\(enumeration.name.trimmed)]") { """
[\(raw: caseElements.map { "(Self.\($0.name.text), \(enumeration.name.text).\($0.name.text))" }.joined(separator: ", "))].reduce(into: []) { result, element in
if contains(element.0) {
result.append(element.1)
}
}
"""
}
options?.leadingTrivia = "/// Array of `\(enumeration.name.text)` enum cases in the `rawValue` bit mask, ordered by declaration.\n"
cases?.leadingTrivia = "/// Array of `\(enumeration.name.text)` enum cases in the `rawValue` bit mask, ordered by declaration.\n"

// Generates an initializer with `options`.
initOptions = try InitializerDeclSyntax("\(accessModifier)init(options: [\(enumeration.name.trimmed)])") { """
self = [\(raw: caseElements.map { "(Self.\($0.name.text), ShippingOption.\($0.name.text))" }.joined(separator: ", "))].reduce(into: []) { result, option in
if options.contains(option.1) {
result.formUnion(option.0)
// Generates an initializer with `cases`.
initCases = try InitializerDeclSyntax("\(accessModifier)init(cases: [\(enumeration.name.trimmed)])") { """
self = [\(raw: caseElements.map { "(Self.\($0.name.text), \(enumeration.name.text).\($0.name.text))" }.joined(separator: ", "))].reduce(into: []) { result, element in
if cases.contains(element.1) {
result.formUnion(element.0)
}
}
"""
}
initOptions?.leadingTrivia = """
initCases?.leadingTrivia = """
/// Creates a new option set with the specified array of `\(enumeration.name.text)` enum cases.
/// - Parameter options: The array of `\(enumeration.name.text)` enum cases corresponding to the `rawValue` bit mask.\n
/// - Parameter cases: The array of `\(enumeration.name.text)` enum cases corresponding to the `rawValue` bit mask.\n
"""
}

Expand All @@ -292,14 +292,14 @@ public struct EnumOptionSetMacro: MemberMacro {
rawValue
initRawValue
initBitIndex
members
options
if let combination { combination }
bitIndices
initBitIndices
if let description { description }
if let debugDescription { debugDescription }
if let options { options }
if let initOptions { initOptions }
if let cases { cases }
if let initCases { initCases }
}

return [.init(setStructure)]
Expand Down
Loading

0 comments on commit 5d510d5

Please sign in to comment.