Options
Swift Package for more powerful Enum
types.




Table of Contents
Introduction
Options provides a features to Enum
and OptionSet
types such as:
- Providing additional value types besides the
RawType rawValue
- Being able to interchange between
Enum
and OptionSet
types
- Using an additional value type for a
Codable
OptionSet
Example
Let’s say you have Enum
type:
enum ContinuousIntegrationSystem {
case github
case travisci
case circleci
case bitrise
}
We want two things:
- Use it as an
OptionSet
so we can store multiple CI sytems
- Store and parse it via a
String
If OptionSet
requires an Int
RawType
, how can we parse and store as String
?
With Options we can enable ContinuousIntegrationSystem
to do both:
enum ContinuousIntegrationSystem: Int, MappedValueCollectionRepresented {
case github
case travisci
case circleci
case bitrise
typealias MappedType = String
static let mappedValues = [
"github",
"travisci",
"circleci",
"bitrise"
]
}
typealias ContinuousIntegrationSystemSet = EnumSet<ContinuousIntegrationSystem>
let systems = ContinuousIntegrationSystemSet([.travisci, .github])
Installation
Swift Package Manager is Apple’s decentralized dependency manager to integrate libraries to your Swift projects. It is now fully integrated with Xcode 11.
To integrate Options into your project using SPM, specify it in your Package.swift file:
let package = Package(
...
dependencies: [
.package(url: "https://github.com/brightdigit/Options", from: "0.1.0")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["Options", ...]),
...
]
)
Usage
So let’s say we our enum
:
enum ContinuousIntegrationSystem: Int {
case github
case travisci
case circleci
case bitrise
}
We want to be able to make it available as an OptionSet
so it needs an RawType
of Int
.
However we want to decode and encode it via Codable
as a String
.
Options has a protocol MappedValueRepresentable
which allows to do that by implementing it.
enum ContinuousIntegrationSystem: Int, MappedValueRepresentable {
case github
case travisci
case circleci
case bitrise
static func rawValue(basedOn string: String) throws -> Int {
if (string == "github") {
return 0
} else {
...
} else {
throw ...
}
}
static func mappedValue(basedOn rawValue: Int) throws -> String {
if (rawValue == 0) {
return "github"
} else {
...
} else {
throw ...
}
}
}
This can be simplified further by using MappedValueCollectionRepresented
.
By using MappedValueCollectionRepresented
, you can simplify implementing MappedValueRepresentable
:
enum ContinuousIntegrationSystem: Int, MappedValueCollectionRepresented {
case github
case travisci
case circleci
case bitrise
static let mappedValues = [
"github",
"travisci",
"circleci",
"bitrise"
]
}
Now we we’ve made it simplifies implementing MappedValueRepresentable
so let’s look how to use it with Codable
.
Codable Enums using a MappedEnum Type
So you’ve setup a MappedValueRepresentable
enum
, the next part is having the MappedType
which in this case is String
the part that’s used in Codable
.
This is where MappedEnum
is used:
struct BuildSetup : Codable {
let ci: MappedEnum<ContinuousIntegrationSystem>
}
Now if the String
can be used in encoding and decoding the value rather than the RawType
Int
:
{
"ci" : "github"
}
Next, let’s take a look how we could use ContinuousIntegrationSystem
in an OptionSet
.
Using Enums in OptionSets with EnumSet
EnumSet
allows you to interchangeably use Enum
with an OptionSet
. EnumSet
is a Generic struct
while takes any Enum
type with a RawType
. So we can create an OptionSet
instance which uses out ContinuousIntegrationSystem
:
let systems = EnumSet<ContinuousIntegrationSystem>([.travisci, .github])
Converting EnumSet to Enum Array
If your Enum
implements CaseIterable
, then you can extract the individual ContinuousIntegrationSystem
enum values with .array()
:
enum ContinuousIntegrationSystem: Int, CaseIterable {
case github
case travisci
case circleci
case bitrise
}
let systems = EnumSet<ContinuousIntegrationSystem>([.travisci, .github])
print(systems.array())
Lastly, let’s put all this together.
Codable EnumSet using a MappedValueRepresentable Enum
If your enum
implements MappedValueRepresentable
and you use it in an EnumSet
, then you can allow for your OptionSet
to be Codable
as an Array
of values rather than the cumulative rawValue
:
enum ContinuousIntegrationSystem: Int, MappedValueCollectionRepresented, CaseIterable {
case github
case travisci
case circleci
case bitrise
static let mappedValues = [
"github",
"travisci",
"circleci",
"bitrise"
]
}
struct BuildSetup : Codable {
let systems: EnumSet<ContinuousIntegrationSystem>
}
let systems = BuildSetup(systems: EnumSet<ContinuousIntegrationSystem>(values: [.travisci, .github]))
For our systems
variable, our Codable
data would be:
{
"systems" : ["travisci", "github"]
}
This will make it easier for making our data human-readable instead of using the rawValue
of 3
.
Further Code Documentation
Documentation Here
License
This code is distributed under the MIT license. See the LICENSE file for more info.
Options
Swift Package for more powerful
Enum
types.Table of Contents
MappedValueRepresentable
EnumMappedValueCollectionRepresented
MappedEnum
TypeEnumSet
EnumSet
to Enum ArrayEnumSet
using aMappedValueRepresentable
EnumIntroduction
Options provides a features to
Enum
andOptionSet
types such as:RawType rawValue
Enum
andOptionSet
typesCodable
OptionSet
Example
Let’s say you have
Enum
type:We want two things:
OptionSet
so we can store multiple CI sytemsString
If
OptionSet
requires anInt
RawType
, how can we parse and store asString
?With Options we can enable
ContinuousIntegrationSystem
to do both:Installation
Swift Package Manager is Apple’s decentralized dependency manager to integrate libraries to your Swift projects. It is now fully integrated with Xcode 11.
To integrate Options into your project using SPM, specify it in your Package.swift file:
Usage
Setting up a MappedValueRepresentable Enum
So let’s say we our
enum
:We want to be able to make it available as an
OptionSet
so it needs anRawType
ofInt
. However we want to decode and encode it viaCodable
as aString
.Options has a protocol
MappedValueRepresentable
which allows to do that by implementing it.This can be simplified further by using
MappedValueCollectionRepresented
.Using MappedValueCollectionRepresented
By using
MappedValueCollectionRepresented
, you can simplify implementingMappedValueRepresentable
:Now we we’ve made it simplifies implementing
MappedValueRepresentable
so let’s look how to use it withCodable
.Codable Enums using a MappedEnum Type
So you’ve setup a
MappedValueRepresentable
enum
, the next part is having theMappedType
which in this case isString
the part that’s used inCodable
.This is where
MappedEnum
is used:Now if the
String
can be used in encoding and decoding the value rather than theRawType
Int
:Next, let’s take a look how we could use
ContinuousIntegrationSystem
in anOptionSet
.Using Enums in OptionSets with EnumSet
EnumSet
allows you to interchangeably useEnum
with anOptionSet
.EnumSet
is a Genericstruct
while takes anyEnum
type with aRawType
. So we can create anOptionSet
instance which uses outContinuousIntegrationSystem
:Converting EnumSet to Enum Array
If your
Enum
implementsCaseIterable
, then you can extract the individualContinuousIntegrationSystem
enum values with.array()
:Lastly, let’s put all this together.
Codable EnumSet using a MappedValueRepresentable Enum
If your
enum
implementsMappedValueRepresentable
and you use it in anEnumSet
, then you can allow for yourOptionSet
to beCodable
as anArray
of values rather than the cumulativerawValue
:For our
systems
variable, ourCodable
data would be:This will make it easier for making our data human-readable instead of using the
rawValue
of3
.Further Code Documentation
Documentation Here
License
This code is distributed under the MIT license. See the LICENSE file for more info.