From 48e6aba776c7f6f6feb15b3d61b1b96eeafebced Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Wed, 6 Feb 2019 14:54:11 -0500 Subject: [PATCH] Add first iteration of blog example --- .idea/misc.xml | 1 + .idea/rust.iml | 5 ++ .idea/workspace.xml | 147 ++++++++++++++++++++++++++++++++------------ blog/Cargo.toml | 7 +++ blog/src/lib.rs | 81 ++++++++++++++++++++++++ blog/src/main.rs | 14 +++++ 6 files changed, 217 insertions(+), 38 deletions(-) create mode 100644 blog/Cargo.toml create mode 100644 blog/src/lib.rs create mode 100644 blog/src/main.rs diff --git a/.idea/misc.xml b/.idea/misc.xml index 69ba99e..37d23de 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -34,6 +34,7 @@ + diff --git a/.idea/rust.iml b/.idea/rust.iml index 8f1c362..0da18db 100644 --- a/.idea/rust.iml +++ b/.idea/rust.iml @@ -137,9 +137,14 @@ + + + + + diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3883477..1f70177 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -13,7 +13,48 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -193,7 +245,7 @@ - + + + - - + - @@ -313,9 +365,10 @@ + - - + + @@ -323,7 +376,7 @@ - + @@ -331,7 +384,7 @@ - + @@ -345,24 +398,6 @@ - - - - - - - - - - - - - - - - - - @@ -785,5 +820,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/Cargo.toml b/blog/Cargo.toml new file mode 100644 index 0000000..c299135 --- /dev/null +++ b/blog/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Timothy Warren "] +edition = "2018" + +[dependencies] diff --git a/blog/src/lib.rs b/blog/src/lib.rs new file mode 100644 index 0000000..87947cf --- /dev/null +++ b/blog/src/lib.rs @@ -0,0 +1,81 @@ +pub struct Post { + state: Option>, + content: String, +} + +impl Post { + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn content(&self) -> &str { + self.state.as_ref().unwrap().content(&self) + } + + pub fn request_review(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.request_review()) + } + } + + pub fn approve(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.approve()) + } + } +} + +trait State { + fn request_review(self: Box) -> Box; + fn approve(self: Box) -> Box; + fn content<'a>(&self, post: &'a Post) -> &'a str { + "" + } +} + +struct Draft {} + +impl State for Draft { + fn request_review(self: Box) -> Box { + Box::new(PendingReview {}) + } + + fn approve(self: Box) -> Box { + self + } +} + +struct PendingReview {} + +impl State for PendingReview { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + Box::new(Published {}) + } +} + +struct Published {} + +impl State for Published { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + self + } + + fn content<'a>(&self, post: &'a Post) -> &'a str { + &post.content + } +} diff --git a/blog/src/main.rs b/blog/src/main.rs new file mode 100644 index 0000000..14b4c08 --- /dev/null +++ b/blog/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +}