diff --git a/examples/pulls.rs b/examples/pulls.rs index 60c34b71..c3aa5470 100644 --- a/examples/pulls.rs +++ b/examples/pulls.rs @@ -51,6 +51,17 @@ fn main() -> Result<()> { Ok(()) }), )?; + + println!("review requests"); + println!("{:#?}", + rt.block_on( + github + .repo("softprops", "hubcaps") + .pulls() + .get(190) + .review_requests() + .get() + )?); Ok(()) } _ => Err("example missing GITHUB_TOKEN".into()), diff --git a/src/lib.rs b/src/lib.rs index 3718e89e..4df0d074 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -155,6 +155,7 @@ pub mod rate_limit; pub mod releases; pub mod repositories; pub mod review_comments; +pub mod review_requests; pub mod search; pub mod stars; pub mod statuses; @@ -938,6 +939,22 @@ where ) } + fn delete_message(&self, uri: &str, message: Vec) -> Future<()> { + Box::new( + self.request_entity::<()>( + Method::DELETE, + &(self.host.clone() + uri), + Some(message), + MediaType::Json, + AuthenticationConstraint::Unconstrained, + ) + .or_else(|err| match err { + Error(ErrorKind::Codec(_), _) => Ok(()), + otherwise => Err(otherwise), + }), + ) + } + fn post(&self, uri: &str, message: Vec) -> Future where D: DeserializeOwned + 'static + Send, diff --git a/src/pulls/mod.rs b/src/pulls/mod.rs index 7699d974..803065a6 100644 --- a/src/pulls/mod.rs +++ b/src/pulls/mod.rs @@ -12,6 +12,7 @@ use issues::{IssueAssignees, IssueLabels, Sort as IssueSort, State}; use labels::Label; use pull_commits::PullCommits; use review_comments::ReviewComments; +use review_requests::ReviewRequests; use users::User; use {unfold, Future, Github, SortDirection, Stream}; @@ -148,6 +149,15 @@ impl PullRequest { ) } + pub fn review_requests(&self) -> ReviewRequests { + ReviewRequests::new( + self.github.clone(), + self.owner.clone(), + self.repo.clone(), + self.number, + ) + } + /// returns pull commits interface pub fn commits(&self) -> PullCommits { PullCommits::new( diff --git a/src/review_requests/mod.rs b/src/review_requests/mod.rs new file mode 100644 index 00000000..951e43ed --- /dev/null +++ b/src/review_requests/mod.rs @@ -0,0 +1,78 @@ +//! Review requests interface + +extern crate futures; +extern crate serde_json; + +use hyper::client::connect::Connect; + +use pulls::Pull; +use teams::Team; +use users::User; +use {Future, Github}; + +/// A structure for interfacing with review requests +pub struct ReviewRequests +where + C: Clone + Connect + 'static, +{ + github: Github, + owner: String, + repo: String, + number: u64, +} + +impl ReviewRequests { + #[doc(hidden)] + pub fn new(github: Github, owner: O, repo: R, number: u64) -> Self + where + O: Into, + R: Into, + { + ReviewRequests { + github, + owner: owner.into(), + repo: repo.into(), + number, + } + } + + /// list requested reviews + pub fn get(&self) -> Future { + self.github.get::(&self.path()) + } + + /// Add new requested reviews + pub fn create(&self, review_request: &ReviewRequestOptions) -> Future { + self.github.post(&self.path(), json!(review_request)) + } + + /// Delete a review request + pub fn delete(&self, review_request: &ReviewRequestOptions) -> Future<()> { + self.github + .delete_message(&self.path(), json!(review_request)) + } + + fn path(&self) -> String { + format!( + "/repos/{}/{}/pulls/{}/requested_reviewers", + self.owner, self.repo, self.number + ) + } +} + +// representations (todo: replace with derive_builder) + +#[derive(Default, Serialize)] +pub struct ReviewRequestOptions { + /// An array of user `logins` that will be requested. + /// Note, each login must be a collaborator. + pub reviewers: Vec, + /// An array of team `slugs` that will be requested. + pub team_reviewers: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct ReviewRequest { + pub users: Vec, + pub teams: Vec, +}