summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan <nathan.leniz@mongodb.com>2021-03-29 02:11:46 -0400
committerGitHub <noreply@github.com>2021-03-29 08:11:46 +0200
commit8bd8e1581214d79f056dea660674bba67172bfed (patch)
tree070bde08d5bf74ebac66d4afa1e78fdd2bd04ffa
parent88f622371425d29e18889a90430b7dcf93ea743b (diff)
List comments for repo and pr (#82)
Adds functionality to list comments for a repo and a pr. As part of this, a Comment model was added, as well as a comments::Sort param enum.
-rw-r--r--src/api/pulls.rs26
-rw-r--r--src/api/pulls/comment.rs113
-rw-r--r--src/models/pulls.rs39
-rw-r--r--src/params.rs11
4 files changed, 189 insertions, 0 deletions
diff --git a/src/api/pulls.rs b/src/api/pulls.rs
index 5dcd929..24d65d2 100644
--- a/src/api/pulls.rs
+++ b/src/api/pulls.rs
@@ -1,5 +1,6 @@
//! The pull request API.
+mod comment;
mod create;
mod list;
mod merge;
@@ -214,6 +215,31 @@ impl<'octo> PullRequestHandler<'octo> {
self.http_get(url, None::<&()>).await
}
+ /// Creates a new `ListCommentsBuilder` that can be configured to list and
+ /// filter `Comments` for a particular pull request. If no pull request is
+ /// specified, lists comments for the whole repo.
+ /// ```no_run
+ /// # async fn run() -> octocrab::Result<()> {
+ /// # let octocrab = octocrab::Octocrab::default();
+ /// use octocrab::params;
+ ///
+ /// let page = octocrab.pulls("owner", "repo").list_comments(Some(5))
+ /// // Optional Parameters
+ /// .sort(params::pulls::comments::Sort::Created)
+ /// .direction(params::Direction::Ascending)
+ /// .per_page(100)
+ /// .page(5u32)
+ /// .since(chrono::Utc::now() - chrono::Duration::days(1))
+ /// // Send the request
+ /// .send()
+ /// .await?;
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn list_comments(&self, pr: Option<u64>) -> comment::ListCommentsBuilder {
+ comment::ListCommentsBuilder::new(self, pr)
+ }
+
/// Creates a new `MergePullRequestsBuilder` that can be configured used to
/// merge a pull request.
/// ```no_run
diff --git a/src/api/pulls/comment.rs b/src/api/pulls/comment.rs
new file mode 100644
index 0000000..d639ff2
--- /dev/null
+++ b/src/api/pulls/comment.rs
@@ -0,0 +1,113 @@
+use super::*;
+
+/// A builder pattern struct for listing comments.
+///
+/// created by [`PullRequestHandler::list_comments`]
+///
+/// [`PullRequestHandler::list_comments`]: ./struct.PullRequestHandler.html#method.list_comments
+#[derive(serde::Serialize)]
+pub struct ListCommentsBuilder<'octo, 'b> {
+ #[serde(skip)]
+ handler: &'b PullRequestHandler<'octo>,
+ #[serde(skip)]
+ pr: Option<u64>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ sort: Option<crate::params::pulls::comments::Sort>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ direction: Option<crate::params::Direction>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ per_page: Option<u8>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ page: Option<u32>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ since: Option<chrono::DateTime<chrono::Utc>>,
+}
+
+impl<'octo, 'b> ListCommentsBuilder<'octo, 'b> {
+ pub(crate) fn new(handler: &'b PullRequestHandler<'octo>, pr: Option<u64>) -> Self {
+ Self {
+ handler,
+ pr,
+ sort: None,
+ direction: None,
+ per_page: None,
+ page: None,
+ since: None,
+ }
+ }
+
+ /// What to sort results by. Can be either `created` or `updated`,
+ pub fn sort(mut self, sort: impl Into<crate::params::pulls::comments::Sort>) -> Self {
+ self.sort = Some(sort.into());
+ self
+ }
+
+ /// The direction of the sort. Can be either ascending or descending.
+ /// Default: descending when sort is `created` or sort is not specified,
+ /// otherwise ascending sort.
+ pub fn direction(mut self, direction: impl Into<crate::params::Direction>) -> Self {
+ self.direction = Some(direction.into());
+ self
+ }
+
+ /// Results per page (max 100).
+ pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
+ self.per_page = Some(per_page.into());
+ self
+ }
+
+ /// Page number of the results to fetch.
+ pub fn page(mut self, page: impl Into<u32>) -> Self {
+ self.page = Some(page.into());
+ self
+ }
+
+ /// Only show notifications updated after the given time.
+ pub fn since(mut self, since: impl Into<chrono::DateTime<chrono::Utc>>) -> Self {
+ self.since = Some(since.into());
+ self
+ }
+
+ /// Sends the actual request.
+ pub async fn send(self) -> crate::Result<Page<crate::models::pulls::Comment>> {
+ let url = format!(
+ "repos/{owner}/{repo}/pulls/{pr}comments",
+ owner = self.handler.owner,
+ repo = self.handler.repo,
+ pr = if let Some(pr) = self.pr {
+ pr.to_string() + "/"
+ } else {
+ "".into()
+ },
+ );
+ self.handler.http_get(url, Some(&self)).await
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ #[tokio::test]
+ async fn serialize() {
+ let octocrab = crate::Octocrab::default();
+ let handler = octocrab.pulls("rust-lang", "rust");
+ let yesterday = chrono::Utc::now() - chrono::Duration::days(1);
+ let list = handler
+ .list_comments(Some(1))
+ .sort(crate::params::pulls::comments::Sort::Updated)
+ .direction(crate::params::Direction::Ascending)
+ .since(yesterday)
+ .per_page(100)
+ .page(1u8);
+
+ assert_eq!(
+ serde_json::to_value(list).unwrap(),
+ serde_json::json!({
+ "sort": "updated",
+ "direction": "asc",
+ "per_page": 100,
+ "page": 1,
+ "since": yesterday
+ })
+ )
+ }
+}
diff --git a/src/models/pulls.rs b/src/models/pulls.rs
index c9c1070..340ac99 100644
--- a/src/models/pulls.rs
+++ b/src/models/pulls.rs
@@ -112,6 +112,9 @@ pub struct Links {
pub commits_link: Option<CommitsLink>,
#[serde(skip_serializing_if = "Option::is_none")]
pub statuses_link: Option<StatusesLink>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ #[serde(rename = "pull_request")]
+ pub pull_request_link: Option<PullRequestLink>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -164,6 +167,11 @@ pub struct StatusesLink {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
+pub struct PullRequestLink {
+ pub href: Url,
+}
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[non_exhaustive]
pub struct Review {
pub id: u64,
pub node_id: String,
@@ -194,6 +202,37 @@ pub enum ReviewState {
Commented,
}
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[non_exhaustive]
+pub struct Comment {
+ pub url: Url,
+ pub pull_request_review_id: u64,
+ pub id: u64,
+ pub node_id: String,
+ pub diff_hunk: String,
+ pub path: String,
+ pub position: Option<u64>,
+ pub original_position: Option<u64>,
+ pub commit_id: String,
+ pub original_commit_id: String,
+ #[serde(default)]
+ pub in_reply_to_id: Option<u64>,
+ pub user: User,
+ pub body: String,
+ pub created_at: chrono::DateTime<chrono::Utc>,
+ pub updated_at: chrono::DateTime<chrono::Utc>,
+ pub html_url: String,
+ pub author_association: String,
+ #[serde(rename = "_links")]
+ pub links: Links,
+ pub start_line: Option<u64>,
+ pub original_start_line: Option<u64>,
+ pub start_side: Option<String>,
+ pub line: Option<u64>,
+ pub original_line: Option<u64>,
+ pub side: Option<String>,
+}
+
// This is rather annoying, but Github uses both SCREAMING_SNAKE_CASE and snake_case
// for the review state, it's uppercase when coming from an API request, but
// lowercase when coming from a webhook payload, so we need to deserialize both,
diff --git a/src/params.rs b/src/params.rs
index e69fcd5..ca53ea9 100644
--- a/src/params.rs
+++ b/src/params.rs
@@ -220,6 +220,17 @@ pub mod pulls {
Squash,
Rebase,
}
+
+ pub mod comments {
+ /// What to sort results by. Can be either `created` or `updated`.
+ #[derive(Debug, Clone, Copy, serde::Serialize)]
+ #[serde(rename_all = "snake_case")]
+ #[non_exhaustive]
+ pub enum Sort {
+ Created,
+ Updated,
+ }
+ }
}
pub mod repos {