Designing posts: state machine
Overall, everything seems fine. Some minor nits and suggestions:


Stylistically, you should have:


trailing commas
spaces on struct literals (Post { content: self.content }

PublishResult makes me think it's a type alias of std::result::Result. I'd advocate for picking a different name.
Instead of matching in your tests and having the not-very-useful assert!(true) and assert!(false), add some helper methods to PublishResult to convert to an expected variant. This is a common pattern for this style of enum. Then you can expect with text in your tests
Dnt ndlssly abbr mthds (Don't needlessly abbreviate methods). Call it request_review instead of req_review.
It's strange to have a test (reject_workflow) with no assertions. I don't think anything's wrong with it, as it's testing the methods and types, it's just a bit implicit. 




struct Post {
    content: String,
}

struct DraftPost {
    content: String,
}

struct PendingPost {
    content: String,
    approvals: u32,
}

impl Post {
    fn new() -&gt; DraftPost {
        DraftPost { content: String::new() }
    }

    fn content(&amp;self) -&gt; &amp;str {
        &amp;self.content
    }
}

impl DraftPost {
    fn request_review(self) -&gt; PendingPost {
        PendingPost {
            content: self.content,
            approvals: 0,
        }
    }

    fn add_text(&amp;mut self, content: &amp;str) {
        self.content.push_str(content);
    }
}

enum PublishResult {
    PendingPost(PendingPost),
    Post(Post),
}

impl PublishResult {
    fn into_pending_post(self) -&gt; Option&lt;PendingPost&gt; {
        use PublishResult::*;
        match self {
            PendingPost(v) =&gt; Some(v),
            _ =&gt; None,
        }
    }

    fn into_post(self) -&gt; Option&lt;Post&gt; {
        use PublishResult::*;
        match self {
            Post(v) =&gt; Some(v),
            _ =&gt; None,
        }
    }
}

impl PendingPost {
    fn approve(&amp;mut self) {
        self.approvals += 1;
    }
    fn reject(self) -&gt; DraftPost {
        DraftPost { content: self.content }
    }
    fn publish(self) -&gt; PublishResult {
        if self.approvals &gt; 1 {
            PublishResult::Post(Post { content: self.content })
        } else {
            PublishResult::PendingPost(self)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn publish_workflow() {
        let mut draft = Post::new();
        draft.add_text("ashish first post");
        let mut pending = draft.request_review();
        pending.approve();
        pending.approve();
        let post = pending.publish().into_post().expect("not a post");
        assert_eq!(post.content(), "ashish first post");
    }

    #[test]
    fn reject_workflow() {
        let mut draft = Post::new();
        draft.add_text("ashish first post");
        let pending = draft.request_review();
        let mut again_draft = pending.reject();
        again_draft.add_text(".. after first one..");
    }

    #[test]
    fn two_approvals_workflow() {
        let mut draft = Post::new();
        draft.add_text("ashish first post");
        let mut pending = draft.request_review();
        pending.approve();
        pending
            .publish()
            .into_pending_post()
            .expect("Not a pending post");
    }
}