lib.rs
pub struct Post {
state: Option<Box<dyn State>>,
content: String,
}
impl Post {
pub fn new() -> Post {
Post {
state: Some(Box::new(DraftPost {})),
content: String::new()
}
}
pub fn add_content(&mut self, content: &str) {
self.content.push_str(content);
}
pub fn content(&self) -> &str {
self.state.as_ref().unwrap().content(self)
}
pub fn request_review(&mut self) {
if let Some(t) = self.state.take() {
self.state = Some(t.request_review())
}
}
pub fn approve(&mut self) {
if let Some(t) = self.state.take() {
self.state = Some(t.approve())
}
}
}
trait State {
fn content<'a>(&self, _post: &'a Post) -> &'a str {
""
}
fn request_review(self: Box<Self>) -> Box<dyn State>;
fn approve(self: Box<Self>) -> Box<dyn State>;
}
struct DraftPost {
}
struct PendingReviewPost {
}
struct PublishedPost {
}
impl State for DraftPost {
fn request_review(self: Box<Self>) -> Box<dyn State> {
Box::new(PendingReviewPost {})
}
fn approve(self: Box<Self>) -> Box<dyn State> {
self
}
}
impl State for PendingReviewPost {
fn request_review(self: Box<Self>) -> Box<dyn State> {
self
}
fn approve(self: Box<Self>) -> Box<dyn State> {
Box::new(PublishedPost {})
}
}
impl State for PublishedPost {
fn content<'a>(&self, post: &'a Post) -> &'a str {
post.content.as_str()
}
fn request_review(self: Box<Self>) -> Box<dyn State> {
self
}
fn approve(self: Box<Self>) -> Box<dyn State> {
self
}
}
main.rs
mod lib;
use oop_exercise::Post;
fn main() {
let t = "I love you";
let mut post = Post::new();
post.add_content(t);
assert_eq!("", post.content());
post.request_review();
assert_eq!("", post.content());
post.approve();
assert_eq!(t, post.content());
}
cargo run:
D:\CLionProjects\oop_exercise>cargo run
warning: unused variable: `post`
--> src\lib.rs:36:27
|
36 | fn content<'a>(&self, post: &'a Post) -> &'a str {
| ^^^^ help: if this is intentional, prefix it with an underscore: `_post`
|
= note: `#[warn(unused_variables)]` on by default
warning: 1 warning emitted
warning: unused variable: `post`
--> src\lib.rs:36:27
|
36 | fn content<'a>(&self, post: &'a Post) -> &'a str {
| ^^^^ help: if this is intentional, prefix it with an underscore: `_post`
|
= note: `#[warn(unused_variables)]` on by default
warning: field is never read: `state`
--> src\lib.rs:2:5
|
2 | state: Option<Box<dyn State>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: associated function is never used: `new`
--> src\lib.rs:7:12
|
7 | pub fn new() -> Post {
| ^^^
warning: associated function is never used: `add_content`
--> src\lib.rs:14:12
|
14 | pub fn add_content(&mut self, content: &str) {
| ^^^^^^^^^^^
warning: associated function is never used: `content`
--> src\lib.rs:18:12
|
18 | pub fn content(&self) -> &str {
| ^^^^^^^
warning: associated function is never used: `request_review`
--> src\lib.rs:22:12
|
22 | pub fn request_review(&mut self) {
| ^^^^^^^^^^^^^^
warning: associated function is never used: `approve`
--> src\lib.rs:28:12
|
28 | pub fn approve(&mut self) {
| ^^^^^^^
warning: 7 warnings emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
Running `target\debug\oop_exercise.exe`
Is this a compiler error, or am I using it incorrectly?