1use crate::config::ConfigProperties;
3use crate::remote::CacheType;
4use crate::Result;
5use crate::{api_traits::MergeRequest, remote::ListRemoteCliArgs};
6use crate::{display, remote};
7use std::fmt::Display;
8use std::io::Write;
9use std::sync::Arc;
10
11use crate::api_traits::{
12 Cicd, CicdJob, CicdRunner, CodeGist, CommentMergeRequest, Deploy, DeployAsset, ProjectMember,
13 RemoteProject, RemoteTag, TrendingProjectURL,
14};
15
16use super::cicd::{JobListBodyArgs, JobListCliArgs, RunnerListBodyArgs, RunnerListCliArgs};
17use super::gist::{GistListBodyArgs, GistListCliArgs};
18use super::merge_request::{
19 CommentMergeRequestListBodyArgs, CommentMergeRequestListCliArgs, MergeRequestListBodyArgs,
20};
21use super::project::{Member, ProjectListBodyArgs, ProjectListCliArgs};
22use super::release::{ReleaseAssetListBodyArgs, ReleaseAssetListCliArgs, ReleaseBodyArgs};
23use super::trending::TrendingCliArgs;
24use super::{cicd::PipelineBodyArgs, merge_request::MergeRequestListCliArgs};
25
26macro_rules! query_pages {
27 ($func_name:ident, $trait_name:ident) => {
28 pub fn $func_name<W: Write>(remote: Arc<dyn $trait_name>, mut writer: W) -> Result<()> {
29 process_num_metadata(remote.num_pages(), MetadataName::Pages, &mut writer)
30 }
31 };
32 ($func_name:ident, $trait_name:ident, $body_args:ident) => {
33 pub fn $func_name<W: Write>(
34 remote: Arc<dyn $trait_name>,
35 body_args: $body_args,
36 mut writer: W,
37 ) -> Result<()> {
38 process_num_metadata(
39 remote.num_pages(body_args),
40 MetadataName::Pages,
41 &mut writer,
42 )
43 }
44 };
45}
46
47macro_rules! query_num_resources {
48 ($func_name:ident, $trait_name:ident) => {
49 pub fn $func_name<W: Write>(remote: Arc<dyn $trait_name>, mut writer: W) -> Result<()> {
50 process_num_metadata(remote.num_resources(), MetadataName::Resources, &mut writer)
51 }
52 };
53 ($func_name:ident, $trait_name:ident, $body_args:ident) => {
54 pub fn $func_name<W: Write>(
55 remote: Arc<dyn $trait_name>,
56 body_args: $body_args,
57 mut writer: W,
58 ) -> Result<()> {
59 process_num_metadata(
60 remote.num_resources(body_args),
61 MetadataName::Resources,
62 &mut writer,
63 )
64 }
65 };
66}
67
68#[derive(Debug)]
69pub enum MetadataName {
70 Pages,
71 Resources,
72}
73
74impl Display for MetadataName {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 MetadataName::Pages => write!(f, "pages"),
78 MetadataName::Resources => write!(f, "resources"),
79 }
80 }
81}
82
83pub fn process_num_metadata<W: Write, T: Display>(
84 num_metadata: Result<Option<T>>,
85 resource_name: MetadataName,
86 mut writer: W,
87) -> Result<()> {
88 let none_msg_info = format!(
89 "Number of {resource_name} not available.\n",
90 resource_name = resource_name
91 );
92 match num_metadata {
93 Ok(Some(count)) => writer.write_all(format!("{total}\n", total = count).as_bytes())?,
94 Ok(None) => {
95 writer.write_all(none_msg_info.as_bytes())?;
96 }
97 Err(e) => {
98 return Err(e);
99 }
100 };
101 Ok(())
102}
103
104query_pages!(num_release_pages, Deploy);
105query_pages!(
106 num_release_asset_pages,
107 DeployAsset,
108 ReleaseAssetListBodyArgs
109);
110query_pages!(num_cicd_pages, Cicd);
111query_pages!(num_runner_pages, CicdRunner, RunnerListBodyArgs);
112query_pages!(num_job_pages, CicdJob, JobListBodyArgs);
113
114query_pages!(
115 num_merge_request_pages,
116 MergeRequest,
117 MergeRequestListBodyArgs
118);
119query_pages!(num_project_pages, RemoteProject, ProjectListBodyArgs);
120query_num_resources!(num_project_resources, RemoteProject, ProjectListBodyArgs);
121
122query_pages!(num_tag_pages, RemoteTag, ProjectListBodyArgs);
123query_num_resources!(num_tag_resources, RemoteTag, ProjectListBodyArgs);
124
125query_pages!(num_project_member_pages, ProjectMember, ProjectListBodyArgs);
126query_num_resources!(
127 num_project_member_resources,
128 ProjectMember,
129 ProjectListBodyArgs
130);
131
132query_pages!(
133 num_comment_merge_request_pages,
134 CommentMergeRequest,
135 CommentMergeRequestListBodyArgs
136);
137
138query_num_resources!(num_release_resources, Deploy);
139query_num_resources!(
140 num_release_asset_resources,
141 DeployAsset,
142 ReleaseAssetListBodyArgs
143);
144query_num_resources!(num_cicd_resources, Cicd);
145query_num_resources!(num_runner_resources, CicdRunner, RunnerListBodyArgs);
146query_num_resources!(num_job_resources, CicdJob, JobListBodyArgs);
147query_num_resources!(
148 num_merge_request_resources,
149 MergeRequest,
150 MergeRequestListBodyArgs
151);
152query_pages!(
153 num_comment_merge_request_resources,
154 CommentMergeRequest,
155 CommentMergeRequestListBodyArgs
156);
157
158query_pages!(num_user_gists, CodeGist);
159query_num_resources!(num_user_gist_resources, CodeGist);
160
161macro_rules! list_resource {
162 ($func_name:ident, $trait_name:ident, $body_args:ident, $cli_args:ident, $embeds_list_args: literal) => {
163 pub fn $func_name<W: Write>(
164 remote: Arc<dyn $trait_name>,
165 body_args: $body_args,
166 cli_args: $cli_args,
167 mut writer: W,
168 ) -> Result<()> {
169 let objs =
170 list_remote_objs!(remote, body_args, cli_args.list_args, writer, $trait_name);
171 display::print(&mut writer, objs, cli_args.list_args.get_args)?;
172 Ok(())
173 }
174 };
175
176 ($func_name:ident, $trait_name:ident, $body_args:ident, $cli_args:ident) => {
177 pub fn $func_name<W: Write>(
178 remote: Arc<dyn $trait_name>,
179 body_args: $body_args,
180 cli_args: $cli_args,
181 mut writer: W,
182 ) -> Result<()> {
183 let objs = list_remote_objs!(remote, body_args, cli_args, writer, $trait_name);
184 display::print(&mut writer, objs, cli_args.get_args)?;
185 Ok(())
186 }
187 };
188}
189
190#[macro_export]
191macro_rules! list_remote_objs {
192 ($remote:expr, $body_args:expr, $cli_args:expr, $writer:expr, $trait_name:ident) => {{
193 let objs = $trait_name::list(&*$remote, $body_args)?;
194 if $cli_args.flush {
195 return Ok(());
196 }
197 if objs.is_empty() {
198 $writer.write_all(b"No resources found.\n")?;
199 return Ok(());
200 }
201 objs
202 }};
203}
204
205list_resource!(
206 list_merge_requests,
207 MergeRequest,
208 MergeRequestListBodyArgs,
209 MergeRequestListCliArgs,
210 true
211);
212
213list_resource!(list_pipelines, Cicd, PipelineBodyArgs, ListRemoteCliArgs);
214list_resource!(
215 list_runners,
216 CicdRunner,
217 RunnerListBodyArgs,
218 RunnerListCliArgs,
219 true
220);
221
222list_resource!(list_jobs, CicdJob, JobListBodyArgs, JobListCliArgs, true);
223
224list_resource!(list_releases, Deploy, ReleaseBodyArgs, ListRemoteCliArgs);
225list_resource!(
226 list_release_assets,
227 DeployAsset,
228 ReleaseAssetListBodyArgs,
229 ReleaseAssetListCliArgs,
230 true
231);
232
233list_resource!(
234 list_user_projects,
235 RemoteProject,
236 ProjectListBodyArgs,
237 ProjectListCliArgs,
238 true
239);
240
241list_resource!(
242 list_project_tags,
243 RemoteTag,
244 ProjectListBodyArgs,
245 ProjectListCliArgs,
246 true
247);
248
249list_resource!(
250 list_project_members,
251 ProjectMember,
252 ProjectListBodyArgs,
253 ProjectListCliArgs,
254 true
255);
256
257list_resource!(
258 list_user_gists,
259 CodeGist,
260 GistListBodyArgs,
261 GistListCliArgs,
262 true
263);
264
265list_resource!(
266 list_merge_request_comments,
267 CommentMergeRequest,
268 CommentMergeRequestListBodyArgs,
269 CommentMergeRequestListCliArgs,
270 true
271);
272
273list_resource!(list_trending, TrendingProjectURL, String, TrendingCliArgs);
274
275pub fn get_user(
276 domain: &str,
277 path: &str,
278 config: &Arc<dyn ConfigProperties>,
279 cli_args: &ListRemoteCliArgs,
280) -> Result<Member> {
281 let remote = remote::get_auth_user(
282 domain.to_string(),
283 path.to_string(),
284 config.clone(),
285 Some(&cli_args.get_args.cache_args),
286 CacheType::File,
287 )?;
288 let user = remote.get_auth_user()?;
289 Ok(user)
290}