1use crate::{
2 api_traits::{ApiOperation, CodeGist, NumberDeltaErr},
3 cmds::gist::{Gist, GistListBodyArgs},
4 io::{HttpResponse, HttpRunner},
5 remote::{query, URLQueryParamBuilder},
6 Result,
7};
8
9use super::Github;
10
11impl<R: HttpRunner<Response = HttpResponse>> CodeGist for Github<R> {
14 fn list(&self, args: GistListBodyArgs) -> crate::Result<Vec<Gist>> {
15 let url = self.auth_user_gist_url(false);
16 query::paged(
17 &self.runner,
18 &url,
19 args.body_args,
20 self.request_headers(),
21 None,
22 ApiOperation::Gist,
23 |value| GithubGistFields::from(value).into(),
24 )
25 }
26
27 fn num_pages(&self) -> Result<Option<u32>> {
28 let url = self.auth_user_gist_url(true);
29 query::num_pages(
30 &self.runner,
31 &url,
32 self.request_headers(),
33 ApiOperation::Gist,
34 )
35 }
36
37 fn num_resources(&self) -> Result<Option<NumberDeltaErr>> {
38 let url = self.auth_user_gist_url(true);
39 query::num_resources(
40 &self.runner,
41 &url,
42 self.request_headers(),
43 ApiOperation::Gist,
44 )
45 }
46}
47
48impl<R> Github<R> {
49 fn auth_user_gist_url(&self, first_page: bool) -> String {
50 let url = format!("{}/gists", self.rest_api_basepath);
51 let mut url_query_param = URLQueryParamBuilder::new(&url);
52 if first_page {
53 url_query_param.add_param("page", "1");
54 }
55 url_query_param.build()
56 }
57}
58
59pub struct GithubGistFields {
60 pub gist: Gist,
61}
62
63impl From<&serde_json::Value> for GithubGistFields {
64 fn from(value: &serde_json::Value) -> Self {
65 let gist = Gist::builder()
66 .url(value["html_url"].as_str().unwrap().to_string())
67 .description(value["description"].as_str().unwrap().to_string())
68 .files(
69 value["files"]
70 .as_object()
71 .unwrap_or(&serde_json::Map::new())
72 .keys()
73 .map(|k| k.to_string())
74 .collect::<Vec<String>>()
75 .join(","),
76 )
77 .created_at(value["created_at"].as_str().unwrap_or("").to_string())
78 .build()
79 .unwrap();
80 Self { gist }
81 }
82}
83
84impl From<GithubGistFields> for Gist {
85 fn from(fields: GithubGistFields) -> Self {
86 fields.gist
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use crate::{
93 setup_client,
94 test::utils::{default_github, ContractType, ResponseContracts},
95 };
96
97 use super::*;
98
99 #[test]
100 fn test_github_list_user_gists() {
101 let contracts = ResponseContracts::new(ContractType::Github).add_contract(
102 200,
103 "list_user_gist.json",
104 None,
105 );
106 let args = GistListBodyArgs::builder().body_args(None).build().unwrap();
107 let (client, github) = setup_client!(contracts, default_github(), dyn CodeGist);
108 let gists = github.list(args).unwrap();
109 assert_eq!("https://api.github.com/gists", *client.url());
110 assert_eq!(1, gists.len());
111 assert_eq!(Some(ApiOperation::Gist), *client.api_operation.borrow());
112 }
113
114 #[test]
115 fn test_github_num_pages() {
116 let contracts = ResponseContracts::new(ContractType::Github).add_contract(
117 200,
118 "list_user_gist.json",
119 None,
120 );
121 let (client, github) = setup_client!(contracts, default_github(), dyn CodeGist);
122 let num_pages = github.num_pages().unwrap();
123 assert_eq!("https://api.github.com/gists?page=1", *client.url());
124 assert_eq!(1, num_pages.unwrap());
125 assert_eq!(Some(ApiOperation::Gist), *client.api_operation.borrow());
126 }
127
128 #[test]
129 fn test_github_num_resources() {
130 let contracts = ResponseContracts::new(ContractType::Github).add_contract(
131 200,
132 "list_user_gist.json",
133 None,
134 );
135 let (client, github) = setup_client!(contracts, default_github(), dyn CodeGist);
136 github.num_resources().unwrap();
137 assert_eq!("https://api.github.com/gists?page=1", *client.url());
138 assert_eq!(Some(ApiOperation::Gist), *client.api_operation.borrow());
139 }
140}