-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy path09-persistent-data.rs
More file actions
90 lines (75 loc) · 2.21 KB
/
09-persistent-data.rs
File metadata and controls
90 lines (75 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use statum::{machine, state, validators};
#[state]
enum State {
Draft(Article),
InReview,
Published,
}
#[machine]
struct Machine<State> {
client: String,
}
#[derive(Debug, PartialEq, Clone)]
enum Status {
Draft,
InReview,
Published,
}
#[derive(Debug, Clone)]
struct Article {
status: Status,
}
#[validators(Machine)]
impl Article {
pub async fn is_draft(&self) -> Result<Article, statum::Error> {
// Generated bindings make machine fields available inside validator methods.
// That lets rehydration fetch extra data without manual parameter plumbing.
let is_valid = pretend_validation_call(client).await?;
if is_valid && self.status == Status::Draft {
Ok(Article {
status: Status::Draft,
})
} else {
Err(statum::Error::InvalidState)
}
}
pub fn is_in_review(&self) -> Result<(), statum::Error> {
if self.status == Status::InReview {
Ok(())
} else {
Err(statum::Error::InvalidState)
}
}
pub fn is_published(&self) -> Result<(), statum::Error> {
if self.status == Status::Published {
Ok(())
} else {
Err(statum::Error::InvalidState)
}
}
}
async fn pretend_validation_call(_client: &str) -> Result<bool, statum::Error> {
Ok(true)
}
pub async fn run() {
let article = Article {
status: Status::Draft,
};
let my_client = "my_client".to_string();
// machine::SomeState is the generated sum type for all possible typed machine states.
let machine_state: machine::SomeState = article
.into_machine()
.client(my_client)
.build()
.await
.unwrap();
// Match once to recover the concrete typed machine.
match machine_state {
machine::SomeState::Draft(_machine) => println!("do thing with Machine<Draft>"),
machine::SomeState::InReview(_machine) => println!("do thing with Machine<InReview>"),
machine::SomeState::Published(_machine) => println!("do thing with Machine<Published>"),
}
// Output:
// Machines client in is_draft validator method: my_client
// do thing with Machine<Draft>
}