I do have two types which are very similarly named.
First is a "StarRating" which defines a rating of 1-5:
enum StarRating:Int,Comparable {
case unknown = 0
case star1
case star2
case star3
case star4
case star5
static func < (lhs: StarRating, rhs: StarRating)->Bool {
return lhs.rawValue < rhs.rawValue
}
}
There are also extensions which conform this to CustomStringConvertable and Codable.
Then we have a StarRatingSet, which is the OptionSet:
struct StarRatingSet:OptionSet {
typealias RawValue = Int
typealias Element = StarRatingSet //<-- This is the line I had to add
var rawValue: Int
static let unknown = StarRatingSet(rawValue: 1 << 0)
static let star1 = StarRatingSet(rawValue: 1 << 1)
static let star2 = StarRatingSet(rawValue: 1 << 2)
static let star3 = StarRatingSet(rawValue: 1 << 3)
static let star4 = StarRatingSet(rawValue: 1 << 4)
static let star5 = StarRatingSet(rawValue: 1 << 5)
static let star4Plus:StarRatingSet = [.star4,.star5]
static let star3Plus:StarRatingSet = [.star3,.star4,.star5]
static let star2Plus:StarRatingSet = [.star2,.star3,.star4,.star5]
static let star1Plus:StarRatingSet = [.star1,.star2,.star3,.star4,.star5]
static let any:StarRatingSet = [.unknown,.star1,.star2,.star3,.star4,.star5]
func contains(_ rating:StarRating) -> Bool {
return self.contains(StarRatingSet(rating))
}
var highest:StarRating {
if self.contains(.star5) {return .star5}
else if self.contains(.star4) {return .star4}
else if self.contains(.star3) {return .star3}
else if self.contains(.star2) {return .star2}
else if self.contains(.star1) {return .star1}
return .unknown
}
var lowest:StarRating {
if self.contains(.star1) {return .star1}
else if self.contains(.star2) {return .star2}
else if self.contains(.star3) {return .star3}
else if self.contains(.star4) {return .star4}
else if self.contains(.star5) {return .star5}
return .unknown
}
}
There are also some extensions which let you create a set from a rating, and to conform this type to Codable.
As you can see, the types are very similar, and they have similarly named members. They are both necessary for our API though. For example, if you are searching for a hotel, you may want to search over a desired set of ratings (StarRatingSet), but any particular hotel returned should only have (or allow) a single rating (StarRating).
Maybe it was inferring StarRating as the Element for StarRatingSet because .starX
has the same name?