Swiftpack.co - allexks/Options as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
allexks/Options
Easily create OptionSets from enums in Swift.
.package(url: "https://github.com/allexks/Options.git", from: "1.2.0")

Options

Made for Swift

Swift Package Manager supported

Build and test GitHub

The swiftier OptionSet. With the help of enums.

The Problem

Let's say that you have some model in your code, for example named Card. This model has a property color which aims to represent its color. Let's also say that all possible card colors are white, blue, black, red, green and all possible combinations of those 5, including none of them.

The standard way this can be handled now in Swift is to create an OptionSet that has flags assigning all colors the numbers 1, 2, 4, 8, 16, ... (so that they can be easily combined with the bitwise operator |), like so:

struct CardColor: OptionSet {
    let rawValue: Int

    init(rawValue: Int) {
        self.rawValue = rawValue
    }

    static let white = CardColor(rawValue: 1 << 0)
    static let blue  = CardColor(rawValue: 1 << 1)
    static let black = CardColor(rawValue: 1 << 2)
    static let red   = CardColor(rawValue: 1 << 3)
    static let green = CardColor(rawValue: 1 << 4)
}

The code snippet above shows the bare minimum for creating an OptionSet that would suit our needs. Although rather simple and straightforward, it still contains quite some boilerplate for just 5 flags: a stored property, an initializer, as well as all literal raw values for all flags manually written.

Our "swifty" intuition tells us that we can do better, can't we?

The Solution

Create a regular enum with all options. They don't need to have a raw value, the only condition is that the enum should conform to CaseIterable (because the way they are arranged in the .allCases array will determine their raw values).

enum CardColor: CaseIterable {
    case white
    case blue
    case black
    case red
    case green
}

Now in order to use the enum like an OptionSet we just need to use the Options struct provided in this library:

let colorless: Options<CardColor> = []
let onlyWhite: Options<CardColor> = [.white]
let bluAndRed: Options<CardColor> = [.blue, .red]

No need for boilerplates and supplying the raw values of all flags.

Extras

The following convenience properties and methods exist:

let allCombined: Options<CardColor> = .all // Equivalent to Options<Topping>([.white, .blue, .black, .red, .green])

let allPossibleBlueColorCombinations = Options<CardColor>.allContaining(.blue) // returns a list of all elements which contain `[.blue]`, sorted ascendingly by their raw values

let favoriteColorCombo: Options<CardColor> = [.white, .blue, .red]
let allPossibleFavoriteColorCombinations = Options<CardColor>.allContaining(favoriteColorCombo) // returns a list of all elements which contain `[.white, .blue, .red]`, sorted ascendingly by their raw values
let sameAsAbove = favoriteColorCombo.allCombinationsContainingSelf

let favoriteComboArray = favoriteColorCombo.decomposed // this is a [CardColor] array containing [.white, .blue, .red]

Limitations

  1. The square brackets should be present even if creating an instance just by using one option, for example:
Options<CardColor>.all.contains(.white)    // this will not compile
Options<CardColor>.all.contains([.white]) //  this will solve it
  1. The supplied enum needs to have a maximum of 64 cases.

License

MIT

GitHub

link
Stars: 1
Last commit: 3 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Submit a free job ad (while I'm testing this). The analytics numbers for this website are here.

Release Notes

1.2.0
3 weeks ago
  • Add decomposed

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics