Hello everyone!
I'm going through the Rust book. I want to implement the exercises given in the section Trade-offs of the State Pattern:
- Add a
reject
method that changes the post’s state fromPendingReview
back toDraft
.- Require two calls to
approve
before the state can be changed toPublished
.- Allow users to add text content only when a post is in the
Draft
state. Hint: have the state object responsible for what might change about the content but not responsible for modifying thePost
.
However I want to implement them into the version that uses different types instead of Object Traits. I'm blocking on the second exercise regarding the double approvals. Here is my attempt:
pub struct Post {
content: String,
}
pub struct PendingReviewPost {
content: String,
approvals: u32,
}
impl PendingReviewPost {
pub fn approve(mut self) -> Post {
// I intentionally left out the creation of PendingReviewPost in the DraftPost.request_review() function
// there I initialize approvals to 0
self.approvals += 1;
if self.approvals < 2 {
// don't know what to actually return here
}
Post {
content: self.content,
}
}
In this chapter we intentionally take ownership of the self
parameter in the approve
function on PendingReviewPost
so we can return a Post
instance and the PendingReviewPost
doesn't exist anymore. The thing is we should call the function twice for it to be approved but since the first call we took the ownership of self
we won't be able to call it again in the main
function. I tried several options but didn't succeed:
- Return an
Option<Post>
and in theif
justreturn None
, we'd have also to make&mut self
to not take ownership. This would work but I don't know how to take ownership of it afterwards once we reached the desired approvals count. If we don't thenPendingReviewPost
andPost
instances we'll both exist in themain function
. Should I copy thecontent
and calldrop()
onself
before returning thePost
?
- Return
Result<Post, PendingReviewPost>
but this felt wrong. - Keep the ownership of
self
but then I'd need to return a new instance ofPendingReviewPost
but that would violate the return type since we can't return bothPost
andPendingReviewPost
from the function. - Add another function that would just increment the
approvals
count and keepapprove
to actually return the newPost
instance but it changes the API and I didn't think it was the purpose of this exercise.
It feels more complicated than I think it should be. What am I missing here?
Thank you for your help.