study_example/object_oriented/
object_oriented_desgin_pattern.rs1pub struct Post {
2 state: Option<Box<dyn State>>,
4 content: String,
5}
6
7impl Post {
8 pub fn new() -> Post {
9 Post {
10 state: Some(Box::new(Draft {})),
11 content: String::new(),
12 }
13 }
14 pub fn add_text(&mut self, text: &str) {
15 self.content.push_str(text);
16 }
17
18 pub fn content(&self) -> &str {
19 self.state.as_ref().unwrap().content(self)
20 }
21
22 pub fn request_review(&mut self) -> &mut Self {
23 if let Some(s) = self.state.take() {
24 self.state = Some(s.request_review())
25 }
26 self
27 }
28
29 pub fn approve(&mut self) -> &mut Self {
30 if let Some(s) = self.state.take() {
31 self.state = Some(s.approve())
32 }
33 self
34 }
35}
36
37trait State {
38 fn request_review(self: Box<Self>) -> Box<dyn State>;
39 fn approve(self: Box<Self>) -> Box<dyn State>;
40 fn content<'a>(&self, post: &'a Post) -> &'a str {
41 ""
42 }
43}
44
45struct Draft {}
46
47impl State for Draft {
48 fn request_review(self: Box<Self>) -> Box<dyn State> {
49 Box::new(PendingReview {})
50 }
51 fn approve(self: Box<Self>) -> Box<dyn State> {
52 self
53 }
54}
55
56struct PendingReview {}
57
58impl State for PendingReview {
59 fn request_review(self: Box<Self>) -> Box<dyn State> {
60 self
61 }
62 fn approve(self: Box<Self>) -> Box<dyn State> {
63 Box::new(Published {})
64 }
65}
66
67struct Published {}
68
69impl State for Published {
70 fn request_review(self: Box<Self>) -> Box<dyn State> {
71 self
72 }
73 fn approve(self: Box<Self>) -> Box<dyn State> {
74 self
75 }
76 fn content<'a>(&self, post: &'a Post) -> &'a str {
77 &post.content
78 }
79}
80
81pub fn object_oriented_desgin_pattern_study() {
82 let mut post = Post::new();
83 post.add_text("I ate a salad for lunch today");
84 let post = post.request_review();
85 let post = post.approve();
86 match &post.state {
87 None => println!("None"),
88 Some(state) => {
89 println!("state:")
90 }
91 }
92}