typestates_comparison/
real_types.rs1pub struct Entity<State> {
5 id: u32,
6 state: State,
7}
8
9pub struct Initial;
11
12pub struct WithA {
14 a: f32,
15}
16
17pub struct WithB {
19 b: bool,
20}
21
22pub struct WithC {
24 a_or_b: AorB,
25 c: char,
26}
27
28enum AorB {
29 A(f32),
30 B(bool),
31}
32
33impl Entity<Initial> {
34 pub fn new(id: u32) -> Entity<Initial> {
35 Entity { id, state: Initial }
36 }
37
38 pub fn add_a(self, a: f32) -> Entity<WithA> {
39 Entity {
40 id: self.id,
41 state: WithA { a },
42 }
43 }
44
45 pub fn add_b(self, b: bool) -> Entity<WithB> {
46 Entity {
47 id: self.id,
48 state: WithB { b },
49 }
50 }
51}
52
53pub trait EntityWithAorB {
55 fn add_c(self, c: char) -> Entity<WithC>;
56}
57
58impl EntityWithAorB for Entity<WithA> {
59 fn add_c(self, c: char) -> Entity<WithC> {
60 self.add_c(c)
61 }
62}
63
64impl EntityWithAorB for Entity<WithB> {
65 fn add_c(self, c: char) -> Entity<WithC> {
66 self.add_c(c)
67 }
68}
69
70impl Entity<WithA> {
71 pub fn add_c(self, c: char) -> Entity<WithC> {
72 Entity {
73 id: self.id,
74 state: WithC {
75 a_or_b: AorB::A(self.state.a),
76 c,
77 },
78 }
79 }
80}
81
82impl Entity<WithB> {
83 pub fn add_c(self, c: char) -> Entity<WithC> {
84 Entity {
85 id: self.id,
86 state: WithC {
87 a_or_b: AorB::B(self.state.b),
88 c,
89 },
90 }
91 }
92}
93
94impl Entity<WithC> {
95 pub fn format(&self) -> String {
96 match self.state.a_or_b {
97 AorB::A(a) => format!("id:{id} a:{a} c:{c}", id = self.id, c = self.state.c),
98 AorB::B(b) => format!("id:{id} b:{b} c:{c}", id = self.id, c = self.state.c),
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 #![allow(clippy::approx_constant)]
106
107 use super::*;
108
109 #[test]
110 fn it_works_with_a() {
111 let e = Entity::new(42);
112 let e = e.add_a(3.14);
113 let e = e.add_c('a');
114 assert_eq!(e.format(), format!("id:42 a:3.14 c:a"));
115 }
116
117 #[test]
118 fn it_works_with_b() {
119 let e = Entity::new(42);
120 let e = e.add_b(true);
121 let e = e.add_c('b');
122 assert_eq!(e.format(), format!("id:42 b:true c:b"));
123 }
124}