Library to enumerate all enum cases (for String
or Int
RawValue
).
EnumList does not relay non memory introspection so it is safe by design and becomes stable in the future Swift releases.
This branch works officially with Swift 4.
If you want to use Swift 3 please check swift3
branch and cocoapods version v0.1.x.
Use CocoaPods to install it with the following command:
$ gem install cocoapods
To integrate EnumList
into your project, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
target 'TARGET' do
pod 'EnumList/Core'
end
Then, run the following command:
$ pod install
In order to make your enum
(with String
rawValue) compatible with EnumList
, add conformance to protocols EnumListStringRaw<NAME_OF_YOUR_ENUM.Values>, RawRepresentable
and define nested struct Values
.
Althouh you have free choose the name and place to define struct
that conformances to StringEnumValues
or IntEnumValues
(e.g. YourEnumName.Values
), it is recommended to keep it as a nested type.
private enum YourEnumName: EnumListStringRaw<YourEnumName.Values>, RawRepresentable{
struct Values:StringEnumValues {
typealias Element = YourEnumName
static var allRaws:Set<String> = []
}
case caseNo1 = "case1"
case caseNo2 = "case2"
//case caseNo3 = "case2" - compile error: RawValues have to be unique
}
YourEnumName.Values.all // Set([.caseNo1, .caseNo2])
YourEnumName.Values.allRaws // Set(["case1", "case2"])
All your cases exist in static Set<YourEnumName>
variable `YourEnumName.Values.all.
You can still create your enum
instance as previously, with literal intialization init?(rawValue:)
:
let myCase = YourEnumName(rawValue: "case1") // myCase = .caseNo1
If you cannot use literals (e.g. when you have only String
instance passed you from somewhere else), you can create it using init?(raw:)
initializer:
let someString = "case1"
...
let myCase = YourEnumName(raw: someString) // myCase = .caseNo1
let myOtherCase = YourEnumName(raw: "case1") // myOtherCase = .caseNo1
EnumList
works the same when dealing with Int
rawValues:
private enum YourIntEnum: EnumListIntRaw<YourIntEnum.Values>, RawRepresentable{
struct Values:IntEnumValues {
typealias Element = YourIntEnum
static var allRaws:Set<Int> = []
}
case caseNo1 = 1
case caseNo2 = 3
}
YourIntEnum.Values.all // Set([.caseNo1, .caseNo2])
YourIntEnum.Values.allRaws // Set([1, 2])
let myCase = YourIntEnum(rawValue: 1) // .caseNo1
Same as with standard enum
, you don't need to specify all rawValues manually. Compiler will fill it for you, with the same String
raw values, as a name of a case. You can mix cases with custom/automatic rawValue
:
private enum YourEnumName: EnumListStringRaw<YourEnumName.Values>, RawRepresentable{
struct Values:StringEnumValues {
typealias Element = YourEnumName
static var allRaws:Set<String> = []
}
case caseNo1 // is equivalent to case caseNo1 = "caseNo1"
case caseNo2 = "case2"
}
YourEnumName.Values.all // Set([.caseNo1, .caseNo2])
YourEnumName.Values.allRaws // Set(["caseNo1", "case2"])
YourEnumName.Values.allRawValues
for grabing all raw values (which are a Set<String>
or Set<Int>
, depending of your enum
deifinition).
Note: YourEnumName.Values.initialize()
or YourEnumName.Values.all
are not required to call before anymore.
Swift does not allow to create several enum
cases with same literal. It applies also for EnumList
:
private enum YourEnumName: EnumListStringRaw<YourEnumName.Values>, RawRepresentable{
struct Values:StringEnumValues {
typealias Element = YourEnumName
static var allRaws:Set<String> = []
}
case caseNo1 = "case1"
//case caseNo2 = "case1" - compile error: RawValues have to be unique
}
EnumList
is compatible with Swift4 out-of-the box.
In addition, it supports Codable
protocol as seamlessly as "normal" enums --- just add conformance to Codable
(or separatelly Encodable
and/or Decodable
):
private enum YourEnumName: EnumListStringRaw<YourEnumName.Values>, RawRepresentable, Codable{
struct Values:StringEnumValues {
typealias Element = YourEnumName
static var allRaws:Set<String> = []
}
case caseNo1 = "case1"
case caseNo2 = "case2"
}
Integration with Unbox
If you want use your enum
with Unbox
framework, include additional subspec, EnumList/Unbox
to your Podfile
:
target 'TARGET' do
pod 'EnumList/Core'
pod 'EnumList/Unbox'
end
then by conforming your enum to UnboxableEnum
, it works out of a box:
private enum EnumForUnbox: EnumListStringRaw<EnumForUnbox.Values>, RawRepresentable, UnboxableEnum{
struct Values:StringEnumValues {
typealias Element = EnumForUnbox
static var allRaws:Set<String> = []
}
case caseNo1 = "case1"
case caseNo2 = "case2"
}
let dictionary:[String:Any] = ["data":"case1"]
let a = Unboxer(dictionary:dictionary)
let unboxEnum:EnumForUnbox = try a.unbox(key: "data") // .caseNo1
Library is covered with unit tests: to run tests integrated with EnumListPoroject.xcodeworkspace
project: install all CocoaPods dependencies (pod install
in your terminal) and run default unit tests (⌘+U).
To test all unit tests from a commandline, call 'fastlane test' in the Project
directory.
Use fastlane
to build a project: fastlane Readme
We use SemVer for versioning. For the versions available, see the tags on this repository.
EnumList
relies on a fact that that if we try to initialise an enum using init(rawValue:)
, Swift takes all values of its RawRepresentable
(that have corresponding case
) one by one and compare it with your rawValue
, until finds equal value. Therefore, if we try to initialise with some rawValue
that does not match any case, EnumList
will have a chance to gather all rawValues with corresponding enum inside ==
operator implementation. This library provides generic struct (String
or Int
representable) that you define as dedicated RawRepresentable
type for your enum.
You can find details in the following document.
- Bartosz Polaczyk - polac24
See also the list of contributors who participated in this project.
This project is licensed under the MIT License - see the LICENSE file for details