1use std::collections::HashMap;
3
4use serde::{Deserialize, Serialize};
5use url::form_urlencoded;
6
7use crate::users::User;
8use crate::{Future, Github};
9
10pub struct Comments {
12 github: Github,
13 owner: String,
14 repo: String,
15 number: u64,
16}
17
18impl Comments {
19 #[doc(hidden)]
20 pub fn new<O, R>(github: Github, owner: O, repo: R, number: u64) -> Self
21 where
22 O: Into<String>,
23 R: Into<String>,
24 {
25 Comments {
26 github,
27 owner: owner.into(),
28 repo: repo.into(),
29 number,
30 }
31 }
32
33 pub fn create(&self, comment: &CommentOptions) -> Future<Comment> {
35 self.github.post(&self.path(), json!(comment))
36 }
37
38 pub fn list(&self, options: &CommentListOptions) -> Future<Vec<Comment>> {
40 let mut uri = vec![self.path()];
41 if let Some(query) = options.serialize() {
42 uri.push(query);
43 }
44 self.github.get(&uri.join("?"))
45 }
46
47 fn path(&self) -> String {
48 format!(
49 "/repos/{}/{}/issues/{}/comments",
50 self.owner, self.repo, self.number
51 )
52 }
53}
54
55#[derive(Debug, Deserialize)]
58pub struct Comment {
59 pub id: u64,
60 pub url: String,
61 pub html_url: String,
62 pub body: String,
63 pub user: User,
64 pub created_at: String,
65 pub updated_at: String,
66}
67
68#[derive(Debug, Serialize)]
69pub struct CommentOptions {
70 pub body: String,
71}
72
73#[derive(Default)]
74pub struct CommentListOptions {
75 params: HashMap<&'static str, String>,
76}
77
78impl CommentListOptions {
79 pub fn builder() -> CommentListOptionsBuilder {
80 CommentListOptionsBuilder::default()
81 }
82
83 pub fn serialize(&self) -> Option<String> {
85 if self.params.is_empty() {
86 None
87 } else {
88 let encoded: String = form_urlencoded::Serializer::new(String::new())
89 .extend_pairs(&self.params)
90 .finish();
91 Some(encoded)
92 }
93 }
94}
95
96#[derive(Default)]
97pub struct CommentListOptionsBuilder(CommentListOptions);
98
99impl CommentListOptionsBuilder {
100 pub fn since<S>(&mut self, since: S) -> &mut Self
101 where
102 S: Into<String>,
103 {
104 self.0.params.insert("since", since.into());
105 self
106 }
107
108 pub fn build(&self) -> CommentListOptions {
109 CommentListOptions {
110 params: self.0.params.clone(),
111 }
112 }
113}