1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use super::*;
use crate::models;

#[derive(serde::Serialize)]
pub struct UpdateIssueBuilder<'octo, 'a, 'b, 'c, 'd, 'e> {
    #[serde(skip)]
    handler: &'a IssueHandler<'octo>,
    #[serde(skip)]
    number: u64,
    title: Option<&'b str>,
    body: Option<&'c str>,
    assignees: Option<&'d [String]>,
    state: Option<models::IssueState>,
    milestone: Option<u64>,
    labels: Option<&'e [String]>,
}

impl<'octo, 'a, 'b, 'c, 'd, 'e> UpdateIssueBuilder<'octo, 'a, 'b, 'c, 'd, 'e> {
    pub(crate) fn new(handler: &'a IssueHandler<'octo>, number: u64) -> Self {
        Self {
            handler,
            number,
            title: None,
            body: None,
            assignees: None,
            state: None,
            milestone: None,
            labels: None,
        }
    }

    /// The title of the issue.
    pub fn title(mut self, title: &'b (impl AsRef<str> + ?Sized)) -> Self {
        self.title = Some(title.as_ref());
        self
    }

    /// The body of the issue.
    pub fn body(mut self, body: &'c (impl AsRef<str> + ?Sized)) -> Self {
        self.body = Some(body.as_ref());
        self
    }

    /// The assignees of the issue.
    pub fn assignees(mut self, assignees: &'d (impl AsRef<[String]> + ?Sized)) -> Self {
        self.assignees = Some(assignees.as_ref());
        self
    }

    /// The state of the issue.
    pub fn state(mut self, state: impl Into<models::IssueState>) -> Self {
        self.state = Some(state.into());
        self
    }

    /// The milestone of the issue.
    pub fn milestone(mut self, milestone: impl Into<u64>) -> Self {
        self.milestone = Some(milestone.into());
        self
    }

    /// The labels of the issue.
    pub fn labels(mut self, labels: &'e (impl AsRef<[String]> + ?Sized)) -> Self {
        self.labels = Some(labels.as_ref());
        self
    }

    /// Send the actual request.
    pub async fn send(self) -> Result<models::Issue> {
        let route = format!(
            "/repos/{owner}/{repo}/issues/{issue}",
            owner = self.handler.owner,
            repo = self.handler.repo,
            issue = self.number,
        );

        self.handler.crab.patch(route, Some(&self)).await
    }
}

#[cfg(test)]
mod tests {
    #[tokio::test]
    async fn serialize() {
        let octocrab = crate::Octocrab::default();
        let handler = octocrab.issues("rust-lang", "rust");
        let assignees = &[String::from("ferris")];
        let labels = &[
            String::from("help wanted"),
            String::from("good first issue"),
        ];
        let update = handler
            .update(1234)
            .title("Updated title")
            .body("New body")
            .state(crate::models::IssueState::Closed)
            .milestone(1234u64)
            .assignees(assignees)
            .labels(labels);

        assert_eq!(
            serde_json::to_value(update).unwrap(),
            serde_json::json!({
                "title": "Updated title",
                "body": "New body",
                "state": "closed",
                "milestone": 1234,
                "assignees": ["ferris"],
                "labels": ["help wanted", "good first issue"],
            })
        )
    }
}