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!("Number of {resource_name} not available.\n");
89 match num_metadata {
90 Ok(Some(count)) => writer.write_all(format!("{count}\n").as_bytes())?,
91 Ok(None) => {
92 writer.write_all(none_msg_info.as_bytes())?;
93 }
94 Err(e) => {
95 return Err(e);
96 }
97 };
98 Ok(())
99}
100
101query_pages!(num_release_pages, Deploy);
102query_pages!(
103 num_release_asset_pages,
104 DeployAsset,
105 ReleaseAssetListBodyArgs
106);
107query_pages!(num_cicd_pages, Cicd);
108query_pages!(num_runner_pages, CicdRunner, RunnerListBodyArgs);
109query_pages!(num_job_pages, CicdJob, JobListBodyArgs);
110
111query_pages!(
112 num_merge_request_pages,
113 MergeRequest,
114 MergeRequestListBodyArgs
115);
116query_pages!(num_project_pages, RemoteProject, ProjectListBodyArgs);
117query_num_resources!(num_project_resources, RemoteProject, ProjectListBodyArgs);
118
119query_pages!(num_tag_pages, RemoteTag, ProjectListBodyArgs);
120query_num_resources!(num_tag_resources, RemoteTag, ProjectListBodyArgs);
121
122query_pages!(num_project_member_pages, ProjectMember, ProjectListBodyArgs);
123query_num_resources!(
124 num_project_member_resources,
125 ProjectMember,
126 ProjectListBodyArgs
127);
128
129query_pages!(
130 num_comment_merge_request_pages,
131 CommentMergeRequest,
132 CommentMergeRequestListBodyArgs
133);
134
135query_num_resources!(num_release_resources, Deploy);
136query_num_resources!(
137 num_release_asset_resources,
138 DeployAsset,
139 ReleaseAssetListBodyArgs
140);
141query_num_resources!(num_cicd_resources, Cicd);
142query_num_resources!(num_runner_resources, CicdRunner, RunnerListBodyArgs);
143query_num_resources!(num_job_resources, CicdJob, JobListBodyArgs);
144query_num_resources!(
145 num_merge_request_resources,
146 MergeRequest,
147 MergeRequestListBodyArgs
148);
149query_pages!(
150 num_comment_merge_request_resources,
151 CommentMergeRequest,
152 CommentMergeRequestListBodyArgs
153);
154
155query_pages!(num_user_gists, CodeGist);
156query_num_resources!(num_user_gist_resources, CodeGist);
157
158macro_rules! list_resource {
159 ($func_name:ident, $trait_name:ident, $body_args:ident, $cli_args:ident, $embeds_list_args: literal) => {
160 pub fn $func_name<W: Write>(
161 remote: Arc<dyn $trait_name>,
162 body_args: $body_args,
163 cli_args: $cli_args,
164 mut writer: W,
165 ) -> Result<()> {
166 let objs =
167 list_remote_objs!(remote, body_args, cli_args.list_args, writer, $trait_name);
168 display::print(&mut writer, objs, cli_args.list_args.get_args)?;
169 Ok(())
170 }
171 };
172
173 ($func_name:ident, $trait_name:ident, $body_args:ident, $cli_args:ident) => {
174 pub fn $func_name<W: Write>(
175 remote: Arc<dyn $trait_name>,
176 body_args: $body_args,
177 cli_args: $cli_args,
178 mut writer: W,
179 ) -> Result<()> {
180 let objs = list_remote_objs!(remote, body_args, cli_args, writer, $trait_name);
181 display::print(&mut writer, objs, cli_args.get_args)?;
182 Ok(())
183 }
184 };
185}
186
187#[macro_export]
188macro_rules! list_remote_objs {
189 ($remote:expr, $body_args:expr, $cli_args:expr, $writer:expr, $trait_name:ident) => {{
190 let objs = $trait_name::list(&*$remote, $body_args)?;
191 if $cli_args.flush {
192 return Ok(());
193 }
194 if objs.is_empty() {
195 $writer.write_all(b"No resources found.\n")?;
196 return Ok(());
197 }
198 objs
199 }};
200}
201
202list_resource!(
203 list_merge_requests,
204 MergeRequest,
205 MergeRequestListBodyArgs,
206 MergeRequestListCliArgs,
207 true
208);
209
210list_resource!(list_pipelines, Cicd, PipelineBodyArgs, ListRemoteCliArgs);
211list_resource!(
212 list_runners,
213 CicdRunner,
214 RunnerListBodyArgs,
215 RunnerListCliArgs,
216 true
217);
218
219list_resource!(list_jobs, CicdJob, JobListBodyArgs, JobListCliArgs, true);
220
221list_resource!(list_releases, Deploy, ReleaseBodyArgs, ListRemoteCliArgs);
222list_resource!(
223 list_release_assets,
224 DeployAsset,
225 ReleaseAssetListBodyArgs,
226 ReleaseAssetListCliArgs,
227 true
228);
229
230list_resource!(
231 list_user_projects,
232 RemoteProject,
233 ProjectListBodyArgs,
234 ProjectListCliArgs,
235 true
236);
237
238list_resource!(
239 list_project_tags,
240 RemoteTag,
241 ProjectListBodyArgs,
242 ProjectListCliArgs,
243 true
244);
245
246list_resource!(
247 list_project_members,
248 ProjectMember,
249 ProjectListBodyArgs,
250 ProjectListCliArgs,
251 true
252);
253
254list_resource!(
255 list_user_gists,
256 CodeGist,
257 GistListBodyArgs,
258 GistListCliArgs,
259 true
260);
261
262list_resource!(
263 list_merge_request_comments,
264 CommentMergeRequest,
265 CommentMergeRequestListBodyArgs,
266 CommentMergeRequestListCliArgs,
267 true
268);
269
270list_resource!(list_trending, TrendingProjectURL, String, TrendingCliArgs);
271
272pub fn get_user(
273 domain: &str,
274 path: &str,
275 config: &Arc<dyn ConfigProperties>,
276 cli_args: &ListRemoteCliArgs,
277) -> Result<Member> {
278 let remote = remote::get_auth_user(
279 domain.to_string(),
280 path.to_string(),
281 config.clone(),
282 Some(&cli_args.get_args.cache_args),
283 CacheType::File,
284 )?;
285 let user = remote.get_auth_user()?;
286 Ok(user)
287}