Skip to content

Commit 4c15f86

Browse files
committed
Conform State<S> & Event<E> to RawRepresentable.
1 parent b42ac6d commit 4c15f86

File tree

6 files changed

+80
-38
lines changed

6 files changed

+80
-38
lines changed

Sources/EventType.swift

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,41 @@ public protocol EventType: Hashable {}
1010

1111
// MARK: Event
1212

13-
/// `EventType` wrapper for handling`.Any` event.
14-
public enum Event<E: EventType>: Hashable
13+
/// `EventType` wrapper for handling `.Any` event.
14+
public enum Event<E: EventType>
1515
{
1616
case Some(E)
1717
case Any
18-
19-
public var value: E?
18+
}
19+
20+
extension Event: Hashable
21+
{
22+
public var hashValue: Int
2023
{
2124
switch self {
22-
case .Some(let x): return x
23-
default: return nil
25+
case .Some(let x): return x.hashValue
26+
case .Any: return _hashValueForAny
27+
}
28+
}
29+
}
30+
31+
extension Event: RawRepresentable
32+
{
33+
public init(rawValue: E?)
34+
{
35+
if let rawValue = rawValue {
36+
self = .Some(rawValue)
37+
}
38+
else {
39+
self = .Any
2440
}
2541
}
2642

27-
public var hashValue: Int
43+
public var rawValue: E?
2844
{
2945
switch self {
30-
case .Some(let x): return x.hashValue
31-
case .Any: return _hashValueForAny
46+
case .Some(let x): return x
47+
default: return nil
3248
}
3349
}
3450
}
@@ -45,6 +61,16 @@ public func == <E: EventType>(lhs: Event<E>, rhs: Event<E>) -> Bool
4561
}
4662
}
4763

64+
public func == <E: EventType>(lhs: Event<E>, rhs: E) -> Bool
65+
{
66+
return lhs.hashValue == rhs.hashValue
67+
}
68+
69+
public func == <E: EventType>(lhs: E, rhs: Event<E>) -> Bool
70+
{
71+
return lhs.hashValue == rhs.hashValue
72+
}
73+
4874
// MARK: NoEvent
4975

5076
/// Useful for creating StateMachine without events, i.e. `StateMachine<MyState, NoEvent>`.

Sources/Machine.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ public class Machine<S: StateType, E: EventType>
7070
/// Check for added routes & routeMappings.
7171
public func hasRoute(event event: E, transition: Transition<S>, userInfo: Any? = nil) -> Bool
7272
{
73-
guard let fromState = transition.fromState.value,
74-
toState = transition.toState.value else
73+
guard let fromState = transition.fromState.rawValue,
74+
toState = transition.toState.rawValue else
7575
{
7676
assertionFailure("State = `.Any` is not supported for `hasRoute()` (always returns `false`)")
7777
return false
@@ -110,7 +110,7 @@ public class Machine<S: StateType, E: EventType>
110110

111111
if let event = event {
112112
for (ev, routeDict) in self._routes {
113-
if ev.value == event || ev == .Any {
113+
if ev.rawValue == event || ev == .Any {
114114
routeDicts += [routeDict]
115115
}
116116
}
@@ -165,7 +165,7 @@ public class Machine<S: StateType, E: EventType>
165165
if transition.fromState == .Some(self.state) || transition.fromState == .Any {
166166
for (_, condition) in keyConditionDict {
167167
// if toState is `.Any`, always treat as identity transition
168-
let toState = transition.toState.value ?? self.state
168+
let toState = transition.toState.rawValue ?? self.state
169169

170170
if _canPassCondition(condition, forEvent: event, fromState: self.state, toState: toState, userInfo: userInfo) {
171171
return toState
@@ -426,7 +426,7 @@ public class Machine<S: StateType, E: EventType>
426426
return
427427
}
428428

429-
if triggeredEvent == event.value || event == .Any {
429+
if triggeredEvent == event.rawValue || event == .Any {
430430
handler(context)
431431
}
432432
}

Sources/StateMachine.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ public final class StateMachine<S: StateType, E: EventType>: Machine<S, E>
4949
/// - Note: This method also checks for event-based-routes.
5050
public func hasRoute(transition: Transition<S>, userInfo: Any? = nil) -> Bool
5151
{
52-
guard let fromState = transition.fromState.value,
53-
toState = transition.toState.value else
52+
guard let fromState = transition.fromState.rawValue,
53+
toState = transition.toState.rawValue else
5454
{
5555
assertionFailure("State = `.Any` is not supported for `hasRoute()` (always returns `false`)")
5656
return false

Sources/StateType.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,37 @@ public protocol StateType: Hashable {}
1010

1111
// MARK: State
1212

13-
/// `StateType` wrapper for handling`.Any` state.
14-
public enum State<S: StateType>: Hashable
13+
/// `StateType` wrapper for handling `.Any` state.
14+
public enum State<S: StateType>
1515
{
1616
case Some(S)
1717
case Any
18-
18+
}
19+
20+
extension State: Hashable
21+
{
1922
public var hashValue: Int
2023
{
2124
switch self {
2225
case .Some(let x): return x.hashValue
2326
case .Any: return _hashValueForAny
2427
}
2528
}
29+
}
30+
31+
extension State: RawRepresentable
32+
{
33+
public init(rawValue: S?)
34+
{
35+
if let rawValue = rawValue {
36+
self = .Some(rawValue)
37+
}
38+
else {
39+
self = .Any
40+
}
41+
}
2642

27-
public var value: S?
43+
public var rawValue: S?
2844
{
2945
switch self {
3046
case .Some(let x): return x

Tests/RouteTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ class RouteTests: _TestCase
1414
func testInit()
1515
{
1616
let route = Route<MyState, NoEvent>(transition: .State0 => .State1, condition: nil)
17-
XCTAssertEqual(route.transition.fromState.value, MyState.State0)
18-
XCTAssertEqual(route.transition.toState.value, MyState.State1)
17+
XCTAssertEqual(route.transition.fromState.rawValue, MyState.State0)
18+
XCTAssertEqual(route.transition.toState.rawValue, MyState.State1)
1919
XCTAssertTrue(route.condition == nil)
2020

2121
let route2 = Route<MyState, NoEvent>(transition: .State1 => .State2, condition: { _ in false })
22-
XCTAssertEqual(route2.transition.fromState.value, MyState.State1)
23-
XCTAssertEqual(route2.transition.toState.value, MyState.State2)
22+
XCTAssertEqual(route2.transition.fromState.rawValue, MyState.State1)
23+
XCTAssertEqual(route2.transition.toState.rawValue, MyState.State2)
2424
XCTAssertTrue(route2.condition != nil)
2525

2626
let route3 = Route<MyState, NoEvent>(transition: .State2 => .State3, condition: { context in false })
27-
XCTAssertEqual(route3.transition.fromState.value, MyState.State2)
28-
XCTAssertEqual(route3.transition.toState.value, MyState.State3)
27+
XCTAssertEqual(route3.transition.fromState.rawValue, MyState.State2)
28+
XCTAssertEqual(route3.transition.toState.rawValue, MyState.State3)
2929
XCTAssertTrue(route3.condition != nil)
3030
}
3131
}

Tests/TransitionTests.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,37 @@ class TransitionTests: _TestCase
1414
func testInit()
1515
{
1616
let transition = Transition<MyState>(fromState: .State0, toState: .State1)
17-
XCTAssertEqual(transition.fromState.value, MyState.State0)
18-
XCTAssertEqual(transition.toState.value, MyState.State1)
17+
XCTAssertEqual(transition.fromState.rawValue, MyState.State0)
18+
XCTAssertEqual(transition.toState.rawValue, MyState.State1)
1919

2020
// shorthand
2121
let transition2 = MyState.State1 => .State0
22-
XCTAssertEqual(transition2.fromState.value, MyState.State1)
23-
XCTAssertEqual(transition2.toState.value, MyState.State0)
22+
XCTAssertEqual(transition2.fromState.rawValue, MyState.State1)
23+
XCTAssertEqual(transition2.toState.rawValue, MyState.State0)
2424
}
2525

2626
func testInit_fromAny()
2727
{
2828
let transition = Transition<MyState>(fromState: .Any, toState: .State1)
29-
XCTAssertNil(transition.fromState.value)
30-
XCTAssertEqual(transition.toState.value, MyState.State1)
29+
XCTAssertNil(transition.fromState.rawValue)
30+
XCTAssertEqual(transition.toState.rawValue, MyState.State1)
3131

3232
// shorthand
3333
let transition2 = .Any => MyState.State0
34-
XCTAssertNil(transition2.fromState.value)
35-
XCTAssertEqual(transition2.toState.value, MyState.State0)
34+
XCTAssertNil(transition2.fromState.rawValue)
35+
XCTAssertEqual(transition2.toState.rawValue, MyState.State0)
3636
}
3737

3838
func testInit_toAny()
3939
{
4040
let transition = Transition<MyState>(fromState: .State0, toState: .Any)
41-
XCTAssertEqual(transition.fromState.value, MyState.State0)
42-
XCTAssertNil(transition.toState.value)
41+
XCTAssertEqual(transition.fromState.rawValue, MyState.State0)
42+
XCTAssertNil(transition.toState.rawValue)
4343

4444
// shorthand
4545
let transition2 = MyState.State1 => .Any
46-
XCTAssertEqual(transition2.fromState.value, MyState.State1)
47-
XCTAssertNil(transition2.toState.value)
46+
XCTAssertEqual(transition2.fromState.rawValue, MyState.State1)
47+
XCTAssertNil(transition2.toState.rawValue)
4848
}
4949

5050
func testNil()

0 commit comments

Comments
 (0)