gr/cmds/
common.rs

1/// Common functions and macros that are used by multiple commands
2use 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}