Last active
May 16, 2019 16:46
-
-
Save ronanrodrigo/1d4d96cd6b35b2ee094e8d2d46f02f8b to your computer and use it in GitHub Desktop.
EnumPoetry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sources/ViewState.swift | |
// Given an enum with some cases | |
protocol EnumPoetry {} | |
enum ViewState<T>: EnumPoetry { | |
case start(T) | |
case loading | |
case completed(Int, String) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Templates/EnumPoetry.stencil | |
// When run this stencil template code with: | |
// sourcery --sources Sources/ --templates Templates/ --output Sources/ | |
{% macro associatedValueTypes associatedValues %}{% for associatedValue in associatedValues %}{% if forloop.first %}{{ associatedValue.typeName }}{% else %}, {{ associatedValue.typeName }}{% endif %}{% endfor %}{% endmacro %} | |
{% macro associatedValueNames associatedValues %}{% for associatedValue in case.associatedValues %}{% if forloop.first %}value{{forloop.counter}}{% else %}, value{{forloop.counter}}{% endif %}{% endfor %}{% endmacro %} | |
{% for enum in types.enums where enum.implements.EnumPoetry %} | |
{{ enum.accessLevel }} extension {{ enum.name }} { | |
{% for case in enum.cases %} | |
{% if case.hasAssociatedValue %} | |
func on{{ case.name|capitalize }}(_ fn: ({% call associatedValueTypes case.associatedValues %}) -> Void) { | |
guard case let .{{ case.name }}({% call associatedValueNames case.associatedValues %}) = self else { return } | |
fn({% call associatedValueNames case.associatedValues %}) | |
} | |
{% else %} | |
func on{{ case.name|capitalize }}(_ fn: () -> Void) { | |
guard case .{{ case.name }} = self else { return } | |
fn() | |
} | |
{% endif %} | |
{% endfor %} | |
} | |
{% endfor %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sources/EnumPoetry.generated.swift | |
// Then you will get this | |
internal extension ViewState { | |
func onStart(_ fn: (T) -> Void) { | |
guard case let .start(value1) = self else { return } | |
fn(value1) | |
} | |
func onLoading(_ fn: () -> Void) { | |
guard case .loading = self else { return } | |
fn() | |
} | |
func onCompleted(_ fn: (Int, String) -> Void) { | |
guard case let .completed(value1, value2) = self else { return } | |
fn(value1, value2) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sources/UsingState.swift | |
// And you can use this way: | |
func handle(state: ViewState<Int>) { | |
state.onStart { number in | |
print("start: \(number)") | |
} | |
state.onLoading { print("loading: ∞") } | |
state.onCompleted { (number, text) in | |
print("completed: \(number) \(text)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment