Skip to content

Commit

Permalink
Merge pull request #2 from tarunon/feature/map
Browse files Browse the repository at this point in the history
rename EnumN->AnyEnumN. adding EnumN.mapK functions
  • Loading branch information
tarunon authored Jul 19, 2017
2 parents 22242ab + 365e73c commit f3bb338
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 28 deletions.
187 changes: 167 additions & 20 deletions Sources/EnumConvertible.swift
Original file line number Diff line number Diff line change
@@ -1,33 +1,50 @@

public enum Enum2<T0, T1> {
public enum AnyEnum2<T0, T1> {
case case0(T0)
case case1(T1)
}

public protocol Enum2Convertible {
associatedtype T0
associatedtype T1
var asEnum: Enum2<T0, T1> { get }
var asEnum: AnyEnum2<T0, T1> { get }
}

extension Enum2: Enum2Convertible {
public var asEnum: Enum2 {
extension AnyEnum2: Enum2Convertible {
public var asEnum: AnyEnum2 {
return self
}
}

extension Enum2Convertible
where T0 == T1
{
func flatten() -> T0 {
public func flatten() -> T0 {
switch self.asEnum {
case .case0(let x): return x
case .case1(let x): return x
}
}
}

public enum Enum3<T0, T1, T2> {
extension Enum2Convertible {
public func map0<T>(_ f: (T0) throws -> T) rethrows -> AnyEnum2<T, T1> {
switch self.asEnum {
case .case0(let x): return try .case0(f(x))
case .case1(let x): return .case1(x)
}
}

public func map1<T>(_ f: (T1) throws -> T) rethrows -> AnyEnum2<T0, T> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return try .case1(f(x))
}
}

}

public enum AnyEnum3<T0, T1, T2> {
case case0(T0)
case case1(T1)
case case2(T2)
Expand All @@ -37,11 +54,11 @@ public protocol Enum3Convertible {
associatedtype T0
associatedtype T1
associatedtype T2
var asEnum: Enum3<T0, T1, T2> { get }
var asEnum: AnyEnum3<T0, T1, T2> { get }
}

extension Enum3: Enum3Convertible {
public var asEnum: Enum3 {
extension AnyEnum3: Enum3Convertible {
public var asEnum: AnyEnum3 {
return self
}
}
Expand All @@ -50,7 +67,7 @@ extension Enum3Convertible
where T0 == T1
, T0 == T2
{
func flatten() -> T0 {
public func flatten() -> T0 {
switch self.asEnum {
case .case0(let x): return x
case .case1(let x): return x
Expand All @@ -59,7 +76,34 @@ extension Enum3Convertible
}
}

public enum Enum4<T0, T1, T2, T3> {
extension Enum3Convertible {
public func map0<T>(_ f: (T0) throws -> T) rethrows -> AnyEnum3<T, T1, T2> {
switch self.asEnum {
case .case0(let x): return try .case0(f(x))
case .case1(let x): return .case1(x)
case .case2(let x): return .case2(x)
}
}

public func map1<T>(_ f: (T1) throws -> T) rethrows -> AnyEnum3<T0, T, T2> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return try .case1(f(x))
case .case2(let x): return .case2(x)
}
}

public func map2<T>(_ f: (T2) throws -> T) rethrows -> AnyEnum3<T0, T1, T> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return .case1(x)
case .case2(let x): return try .case2(f(x))
}
}

}

public enum AnyEnum4<T0, T1, T2, T3> {
case case0(T0)
case case1(T1)
case case2(T2)
Expand All @@ -71,11 +115,11 @@ public protocol Enum4Convertible {
associatedtype T1
associatedtype T2
associatedtype T3
var asEnum: Enum4<T0, T1, T2, T3> { get }
var asEnum: AnyEnum4<T0, T1, T2, T3> { get }
}

extension Enum4: Enum4Convertible {
public var asEnum: Enum4 {
extension AnyEnum4: Enum4Convertible {
public var asEnum: AnyEnum4 {
return self
}
}
Expand All @@ -85,7 +129,7 @@ extension Enum4Convertible
, T0 == T2
, T0 == T3
{
func flatten() -> T0 {
public func flatten() -> T0 {
switch self.asEnum {
case .case0(let x): return x
case .case1(let x): return x
Expand All @@ -95,7 +139,46 @@ extension Enum4Convertible
}
}

public enum Enum5<T0, T1, T2, T3, T4> {
extension Enum4Convertible {
public func map0<T>(_ f: (T0) throws -> T) rethrows -> AnyEnum4<T, T1, T2, T3> {
switch self.asEnum {
case .case0(let x): return try .case0(f(x))
case .case1(let x): return .case1(x)
case .case2(let x): return .case2(x)
case .case3(let x): return .case3(x)
}
}

public func map1<T>(_ f: (T1) throws -> T) rethrows -> AnyEnum4<T0, T, T2, T3> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return try .case1(f(x))
case .case2(let x): return .case2(x)
case .case3(let x): return .case3(x)
}
}

public func map2<T>(_ f: (T2) throws -> T) rethrows -> AnyEnum4<T0, T1, T, T3> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return .case1(x)
case .case2(let x): return try .case2(f(x))
case .case3(let x): return .case3(x)
}
}

public func map3<T>(_ f: (T3) throws -> T) rethrows -> AnyEnum4<T0, T1, T2, T> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return .case1(x)
case .case2(let x): return .case2(x)
case .case3(let x): return try .case3(f(x))
}
}

}

public enum AnyEnum5<T0, T1, T2, T3, T4> {
case case0(T0)
case case1(T1)
case case2(T2)
Expand All @@ -109,11 +192,11 @@ public protocol Enum5Convertible {
associatedtype T2
associatedtype T3
associatedtype T4
var asEnum: Enum5<T0, T1, T2, T3, T4> { get }
var asEnum: AnyEnum5<T0, T1, T2, T3, T4> { get }
}

extension Enum5: Enum5Convertible {
public var asEnum: Enum5 {
extension AnyEnum5: Enum5Convertible {
public var asEnum: AnyEnum5 {
return self
}
}
Expand All @@ -124,7 +207,7 @@ extension Enum5Convertible
, T0 == T3
, T0 == T4
{
func flatten() -> T0 {
public func flatten() -> T0 {
switch self.asEnum {
case .case0(let x): return x
case .case1(let x): return x
Expand All @@ -135,3 +218,67 @@ extension Enum5Convertible
}
}

extension Enum5Convertible {
public func map0<T>(_ f: (T0) throws -> T) rethrows -> AnyEnum5<T, T1, T2, T3, T4> {
switch self.asEnum {
case .case0(let x): return try .case0(f(x))
case .case1(let x): return .case1(x)
case .case2(let x): return .case2(x)
case .case3(let x): return .case3(x)
case .case4(let x): return .case4(x)
}
}

public func map1<T>(_ f: (T1) throws -> T) rethrows -> AnyEnum5<T0, T, T2, T3, T4> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return try .case1(f(x))
case .case2(let x): return .case2(x)
case .case3(let x): return .case3(x)
case .case4(let x): return .case4(x)
}
}

public func map2<T>(_ f: (T2) throws -> T) rethrows -> AnyEnum5<T0, T1, T, T3, T4> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return .case1(x)
case .case2(let x): return try .case2(f(x))
case .case3(let x): return .case3(x)
case .case4(let x): return .case4(x)
}
}

public func map3<T>(_ f: (T3) throws -> T) rethrows -> AnyEnum5<T0, T1, T2, T, T4> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return .case1(x)
case .case2(let x): return .case2(x)
case .case3(let x): return try .case3(f(x))
case .case4(let x): return .case4(x)
}
}

public func map4<T>(_ f: (T4) throws -> T) rethrows -> AnyEnum5<T0, T1, T2, T3, T> {
switch self.asEnum {
case .case0(let x): return .case0(x)
case .case1(let x): return .case1(x)
case .case2(let x): return .case2(x)
case .case3(let x): return .case3(x)
case .case4(let x): return try .case4(f(x))
}
}

}


// MARK: deprecated

@available(*, deprecated, renamed: "AnyEnum2")
public typealias Enum2<T0, T1> = AnyEnum2<T0, T1>
@available(*, deprecated, renamed: "AnyEnum3")
public typealias Enum3<T0, T1, T2> = AnyEnum3<T0, T1, T2>
@available(*, deprecated, renamed: "AnyEnum4")
public typealias Enum4<T0, T1, T2, T3> = AnyEnum4<T0, T1, T2, T3>
@available(*, deprecated, renamed: "AnyEnum5")
public typealias Enum5<T0, T1, T2, T3, T4> = AnyEnum5<T0, T1, T2, T3, T4>
32 changes: 28 additions & 4 deletions Sources/EnumConvertible.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
all = range(n)
res = ["T{} == T{}".format(all[0], i) for i in all[1:]]
return ["where " + res[0]] + [", " + x for x in res[1:]]
def mapReturnType(enumNumber, caseNumber):
return "AnyEnum{}<{}>".format(enumNumber, ", ".join(["T{}".format(i) if i != caseNumber else "T" for i in range(enumNumber)]))

enumNumbers = range(2, int(MAX_SERIAL_NUMBER) + 1)
if len(SPECIFIC_NUMBERS) > 0:
enumNumbers += [int(s) for s in SPECIFIC_NUMBERS.split(',')]
}%

% for enumNumber in enumNumbers:
public enum Enum${enumNumber}<${enumerateT(enumNumber)}> {
public enum AnyEnum${enumNumber}<${enumerateT(enumNumber)}> {
% for caseNumber in range(enumNumber):
case case${caseNumber}(T${caseNumber})
% end
Expand All @@ -24,11 +26,11 @@ public protocol Enum${enumNumber}Convertible {
% for caseNumber in range(enumNumber):
associatedtype T${caseNumber}
% end
var asEnum: Enum${enumNumber}<${enumerateT(enumNumber)}> { get }
var asEnum: AnyEnum${enumNumber}<${enumerateT(enumNumber)}> { get }
}

extension Enum${enumNumber}: Enum${enumNumber}Convertible {
public var asEnum: Enum${enumNumber} {
extension AnyEnum${enumNumber}: Enum${enumNumber}Convertible {
public var asEnum: AnyEnum${enumNumber} {
return self
}
}
Expand All @@ -47,6 +49,28 @@ extension Enum${enumNumber}Convertible
}
}

extension Enum${enumNumber}Convertible {
% for caseNumber in range(enumNumber):
public func map${caseNumber}<T>(_ f: (T${caseNumber}) throws -> T) rethrows -> ${mapReturnType(enumNumber, caseNumber)} {
switch self.asEnum {
% for caseNumber2 in range(enumNumber):
% if caseNumber == caseNumber2:
case .case${caseNumber2}(let x): return try .case${caseNumber2}(f(x))
% else:
case .case${caseNumber2}(let x): return .case${caseNumber2}(x)
% end
% end
}
}

% end
}

% end

// MARK: deprecated

% for enumNumber in enumNumbers:
@available(*, deprecated, renamed: "AnyEnum${enumNumber}")
public typealias Enum${enumNumber}<${enumerateT(enumNumber)}> = AnyEnum${enumNumber}<${enumerateT(enumNumber)}>
% end
8 changes: 4 additions & 4 deletions Tests/EnumConvertibleTests/EnumConvertibleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ enum MyEnum2 {
}

extension MyEnum2: Enum2Convertible {
var asEnum: Enum2<Int, String> {
var asEnum: AnyEnum2<Int, String> {
switch self {
case .int(let int): return .case0(int)
case .str(let str): return .case1(str)
Expand All @@ -22,7 +22,7 @@ enum MyEnum3 {
}

extension MyEnum3: Enum3Convertible {
var asEnum: Enum3<Int, String, Double> {
var asEnum: AnyEnum3<Int, String, Double> {
switch self {
case .int(let int): return .case0(int)
case .str(let str): return .case1(str)
Expand All @@ -39,7 +39,7 @@ enum MyEnum4 {
}

extension MyEnum4: Enum4Convertible {
var asEnum: Enum4<Int, String, Double, [Int]> {
var asEnum: AnyEnum4<Int, String, Double, [Int]> {
switch self {
case .int(let int): return .case0(int)
case .str(let str): return .case1(str)
Expand All @@ -58,7 +58,7 @@ enum MyEnum5 {
}

extension MyEnum5: Enum5Convertible {
var asEnum: Enum5<Int, String, Double, [Int], [String: Int]> {
var asEnum: AnyEnum5<Int, String, Double, [Int], [String: Int]> {
switch self {
case .int(let int): return .case0(int)
case .str(let str): return .case1(str)
Expand Down

0 comments on commit f3bb338

Please sign in to comment.