pub struct Post { content: String, } pub struct DraftPost { content: String, } impl Post { pub fn new() -> DraftPost { DraftPost { content: String::new(), } } pub fn content(&self) -> &str { &self.content } } impl DraftPost { pub fn add_text(&mut self, text: &str) { self.content.push_str(text); } pub fn request_review(self) -> PendingReviewPost { PendingReviewPost { content: self.content, pre_approved: false, } } } pub struct PendingReviewPost { content: String, pre_approved: bool, } pub enum PendingOrPost { PendingReviewPost(PendingReviewPost), Post(Post), } impl PendingReviewPost { pub fn approve(mut self) -> PendingOrPost { if self.pre_approved { PendingOrPost::Post(Post { content: self.content, }) } else { self.pre_approved = true; PendingOrPost::PendingReviewPost(self) } } pub fn reject(self) -> DraftPost { DraftPost { content: self.content, } } } // 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 // } // }